2
0
Эх сурвалжийг харах

Merge pull request #63071 from lawnjelly/skinning2d_bounds

Rémi Verschelde 3 жил өмнө
parent
commit
ccbe083949

+ 1 - 0
drivers/dummy/rasterizer_dummy.h

@@ -483,6 +483,7 @@ public:
 	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) {}
 	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 */
 

+ 7 - 0
drivers/gles2/rasterizer_storage_gles2.cpp

@@ -3731,6 +3731,7 @@ void RasterizerStorageGLES2::skeleton_bone_set_transform_2d(RID p_skeleton, int
 	if (!skeleton->update_list.in_list()) {
 		skeleton_update_list.add(&skeleton->update_list);
 	}
+	skeleton->revision++;
 }
 
 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;
 }
 
+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() {
 	while (blend_shapes_update_list.first()) {
 		Mesh *mesh = blend_shapes_update_list.first()->self();

+ 3 - 0
drivers/gles2/rasterizer_storage_gles2.h

@@ -890,6 +890,7 @@ public:
 		bool use_2d;
 
 		int size;
+		uint32_t revision;
 
 		// TODO use float textures for storage
 
@@ -905,6 +906,7 @@ public:
 		Skeleton() :
 				use_2d(false),
 				size(0),
+				revision(1),
 				tex_id(0),
 				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 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 uint32_t skeleton_get_revision(RID p_skeleton) const;
 
 	void _update_skeleton_transform_buffer(const PoolVector<float> &p_data, size_t p_size);
 

+ 8 - 0
drivers/gles3/rasterizer_storage_gles3.cpp

@@ -5277,6 +5277,8 @@ void RasterizerStorageGLES3::skeleton_bone_set_transform_2d(RID p_skeleton, int
 	if (!skeleton->update_list.in_list()) {
 		skeleton_update_list.add(&skeleton->update_list);
 	}
+
+	skeleton->revision++;
 }
 Transform2D RasterizerStorageGLES3::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const {
 	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;
 }
 
+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() {
 	glActiveTexture(GL_TEXTURE0);
 

+ 3 - 0
drivers/gles3/rasterizer_storage_gles3.h

@@ -920,6 +920,7 @@ public:
 	struct Skeleton : RID_Data {
 		bool use_2d;
 		int size;
+		uint32_t revision;
 		Vector<float> skel_texture;
 		GLuint texture;
 		SelfList<Skeleton> update_list;
@@ -929,6 +930,7 @@ public:
 		Skeleton() :
 				use_2d(false),
 				size(0),
+				revision(1),
 				texture(0),
 				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 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 uint32_t skeleton_get_revision(RID p_skeleton) const;
 
 	/* Light API */
 

+ 32 - 11
servers/visual/rasterizer.h

@@ -448,6 +448,7 @@ public:
 	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 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 */
 
@@ -947,19 +948,24 @@ public:
 		};
 
 		Transform2D xform;
-		bool clip;
-		bool visible;
-		bool behind;
-		bool update_when_visible;
-		//VS::MaterialBlendMode blend_mode;
-		int light_mask;
+		bool clip : 1;
+		bool visible : 1;
+		bool behind : 1;
+		bool update_when_visible : 1;
+		bool distance_field : 1;
+		bool light_masked : 1;
+		mutable bool custom_rect : 1;
+		mutable bool rect_dirty : 1;
+
 		Vector<Command *> commands;
-		mutable bool custom_rect;
-		mutable bool rect_dirty;
 		mutable Rect2 rect;
 		RID material;
 		RID skeleton;
 
+		//VS::MaterialBlendMode blend_mode;
+		int32_t light_mask;
+		mutable uint32_t skeleton_revision;
+
 		Item *next;
 
 		struct CopyBackBuffer {
@@ -975,15 +981,29 @@ public:
 		Item *final_clip_owner;
 		Item *material_owner;
 		ViewportRender *vp_render;
-		bool distance_field;
-		bool light_masked;
 
 		Rect2 global_rect_cache;
 
 		const Rect2 &get_rect() const {
-			if (custom_rect || (!rect_dirty && !update_when_visible)) {
+			if (custom_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
 			int s = commands.size();
@@ -1171,6 +1191,7 @@ public:
 		}
 		Item() {
 			light_mask = 1;
+			skeleton_revision = 0;
 			vp_render = nullptr;
 			next = nullptr;
 			final_clip_owner = nullptr;