1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-30 16:26:50 +00:00

Fix 2D MultiMesh hierarchical culling

Fixes updating local bounds for MultiMeshes used in canvas items by introducing a back link.
This commit is contained in:
lawnjelly
2023-08-01 08:42:30 +01:00
parent 39bbf76584
commit ad577e3c7e
8 changed files with 121 additions and 5 deletions

View File

@@ -395,6 +395,7 @@ public:
virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible);
virtual int multimesh_get_visible_instances(RID p_multimesh) const;
virtual AABB multimesh_get_aabb(RID p_multimesh) const;
virtual void multimesh_attach_canvas_item(RID p_multimesh, RID p_canvas_item, bool p_attach) = 0;
virtual RID _multimesh_create() = 0;
virtual void _multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format, VS::MultimeshCustomDataFormat p_data = VS::MULTIMESH_CUSTOM_DATA_NONE) = 0;
@@ -817,6 +818,8 @@ public:
TYPE_MULTIRECT,
};
virtual bool contains_reference(const RID &p_rid) const { return false; }
Type type;
virtual ~Command() {}
};
@@ -946,7 +949,15 @@ public:
RID multimesh;
RID texture;
RID normal_map;
RID canvas_item;
virtual bool contains_reference(const RID &p_rid) const { return multimesh == p_rid; }
CommandMultiMesh() { type = TYPE_MULTIMESH; }
virtual ~CommandMultiMesh() {
// Remove any backlinks from multimesh to canvas item.
if (multimesh.is_valid()) {
RasterizerStorage::base_singleton->multimesh_attach_canvas_item(multimesh, canvas_item, false);
}
}
};
struct CommandParticles : public Command {
@@ -1199,6 +1210,20 @@ public:
return rect;
}
void remove_references(const RID &p_rid) {
for (int i = commands.size() - 1; i >= 0; i--) {
if (commands[i]->contains_reference(p_rid)) {
memdelete(commands[i]);
// This could possibly be unordered if occurring close
// to canvas_item deletion, but is
// unlikely to make much performance difference,
// and is safer.
commands.remove(i);
}
}
}
void clear() {
for (int i = 0; i < commands.size(); i++) {
memdelete(commands[i]);