1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-22 15:06:45 +00:00

Fix skeleton 2D stale bounding rect

Adds special logic for handling skeleton bounding rect updates. Previously these were never being updated because the canvas item is never set to "rect_dirty".
This commit is contained in:
lawnjelly
2022-07-16 13:27:48 +01:00
parent c55e8dd516
commit 18bb668a2e
6 changed files with 54 additions and 11 deletions

View File

@@ -483,6 +483,7 @@ public:
Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const { return Transform(); } Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const { return Transform(); }
void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) {} void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) {}
Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const { return Transform2D(); } Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const { return Transform2D(); }
uint32_t skeleton_get_revision(RID p_skeleton) const { return 0; }
/* Light API */ /* Light API */

View File

@@ -3731,6 +3731,7 @@ void RasterizerStorageGLES2::skeleton_bone_set_transform_2d(RID p_skeleton, int
if (!skeleton->update_list.in_list()) { if (!skeleton->update_list.in_list()) {
skeleton_update_list.add(&skeleton->update_list); skeleton_update_list.add(&skeleton->update_list);
} }
skeleton->revision++;
} }
Transform2D RasterizerStorageGLES2::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const { Transform2D RasterizerStorageGLES2::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const {
@@ -3763,6 +3764,12 @@ void RasterizerStorageGLES2::skeleton_set_base_transform_2d(RID p_skeleton, cons
skeleton->base_transform_2d = p_base_transform; skeleton->base_transform_2d = p_base_transform;
} }
uint32_t RasterizerStorageGLES2::skeleton_get_revision(RID p_skeleton) const {
const Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND_V(!skeleton, 0);
return skeleton->revision;
}
void RasterizerStorageGLES2::update_dirty_blend_shapes() { void RasterizerStorageGLES2::update_dirty_blend_shapes() {
while (blend_shapes_update_list.first()) { while (blend_shapes_update_list.first()) {
Mesh *mesh = blend_shapes_update_list.first()->self(); Mesh *mesh = blend_shapes_update_list.first()->self();

View File

@@ -890,6 +890,7 @@ public:
bool use_2d; bool use_2d;
int size; int size;
uint32_t revision;
// TODO use float textures for storage // TODO use float textures for storage
@@ -905,6 +906,7 @@ public:
Skeleton() : Skeleton() :
use_2d(false), use_2d(false),
size(0), size(0),
revision(1),
tex_id(0), tex_id(0),
update_list(this) { update_list(this) {
} }
@@ -924,6 +926,7 @@ public:
virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform); virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform);
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const; virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const;
virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform); virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform);
virtual uint32_t skeleton_get_revision(RID p_skeleton) const;
void _update_skeleton_transform_buffer(const PoolVector<float> &p_data, size_t p_size); void _update_skeleton_transform_buffer(const PoolVector<float> &p_data, size_t p_size);

View File

@@ -5277,6 +5277,8 @@ void RasterizerStorageGLES3::skeleton_bone_set_transform_2d(RID p_skeleton, int
if (!skeleton->update_list.in_list()) { if (!skeleton->update_list.in_list()) {
skeleton_update_list.add(&skeleton->update_list); skeleton_update_list.add(&skeleton->update_list);
} }
skeleton->revision++;
} }
Transform2D RasterizerStorageGLES3::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const { Transform2D RasterizerStorageGLES3::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const {
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
@@ -5310,6 +5312,12 @@ void RasterizerStorageGLES3::skeleton_set_base_transform_2d(RID p_skeleton, cons
skeleton->base_transform_2d = p_base_transform; skeleton->base_transform_2d = p_base_transform;
} }
uint32_t RasterizerStorageGLES3::skeleton_get_revision(RID p_skeleton) const {
const Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND_V(!skeleton, 0);
return skeleton->revision;
}
void RasterizerStorageGLES3::update_dirty_skeletons() { void RasterizerStorageGLES3::update_dirty_skeletons() {
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);

View File

@@ -920,6 +920,7 @@ public:
struct Skeleton : RID_Data { struct Skeleton : RID_Data {
bool use_2d; bool use_2d;
int size; int size;
uint32_t revision;
Vector<float> skel_texture; Vector<float> skel_texture;
GLuint texture; GLuint texture;
SelfList<Skeleton> update_list; SelfList<Skeleton> update_list;
@@ -929,6 +930,7 @@ public:
Skeleton() : Skeleton() :
use_2d(false), use_2d(false),
size(0), size(0),
revision(1),
texture(0), texture(0),
update_list(this) { update_list(this) {
} }
@@ -948,6 +950,7 @@ public:
virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform); virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform);
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const; virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const;
virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform); virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform);
virtual uint32_t skeleton_get_revision(RID p_skeleton) const;
/* Light API */ /* Light API */

View File

@@ -448,6 +448,7 @@ public:
virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) = 0; virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) = 0;
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const = 0; virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const = 0;
virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) = 0; virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) = 0;
virtual uint32_t skeleton_get_revision(RID p_skeleton) const = 0;
/* Light API */ /* Light API */
@@ -947,19 +948,24 @@ public:
}; };
Transform2D xform; Transform2D xform;
bool clip; bool clip : 1;
bool visible; bool visible : 1;
bool behind; bool behind : 1;
bool update_when_visible; bool update_when_visible : 1;
//VS::MaterialBlendMode blend_mode; bool distance_field : 1;
int light_mask; bool light_masked : 1;
mutable bool custom_rect : 1;
mutable bool rect_dirty : 1;
Vector<Command *> commands; Vector<Command *> commands;
mutable bool custom_rect;
mutable bool rect_dirty;
mutable Rect2 rect; mutable Rect2 rect;
RID material; RID material;
RID skeleton; RID skeleton;
//VS::MaterialBlendMode blend_mode;
int32_t light_mask;
mutable uint32_t skeleton_revision;
Item *next; Item *next;
struct CopyBackBuffer { struct CopyBackBuffer {
@@ -975,15 +981,29 @@ public:
Item *final_clip_owner; Item *final_clip_owner;
Item *material_owner; Item *material_owner;
ViewportRender *vp_render; ViewportRender *vp_render;
bool distance_field;
bool light_masked;
Rect2 global_rect_cache; Rect2 global_rect_cache;
const Rect2 &get_rect() const { const Rect2 &get_rect() const {
if (custom_rect || (!rect_dirty && !update_when_visible)) { if (custom_rect) {
return rect; return rect;
} }
if (!rect_dirty && !update_when_visible) {
if (skeleton == RID()) {
return rect;
} else {
// special case for skeletons
uint32_t rev = RasterizerStorage::base_singleton->skeleton_get_revision(skeleton);
if (rev == skeleton_revision) {
// no change to the skeleton since we last calculated the bounding rect
return rect;
} else {
// We need to recalculate.
// Mark as done for next time.
skeleton_revision = rev;
}
}
}
//must update rect //must update rect
int s = commands.size(); int s = commands.size();
@@ -1171,6 +1191,7 @@ public:
} }
Item() { Item() {
light_mask = 1; light_mask = 1;
skeleton_revision = 0;
vp_render = nullptr; vp_render = nullptr;
next = nullptr; next = nullptr;
final_clip_owner = nullptr; final_clip_owner = nullptr;