Selaa lähdekoodia

[unity] Fixed SkeletonGraphic unnecessary redundant mesh update at color change. Changed update code to use SetVerticesDirty and Rebuild. Closes #2049.

Harald Csaszar 3 vuotta sitten
vanhempi
commit
c5df7b7bdb

+ 68 - 53
spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs

@@ -235,7 +235,7 @@ namespace Spine.Unity {
 		public override void Rebuild (CanvasUpdate update) {
 		public override void Rebuild (CanvasUpdate update) {
 			base.Rebuild(update);
 			base.Rebuild(update);
 			if (canvasRenderer.cull) return;
 			if (canvasRenderer.cull) return;
-			if (update == CanvasUpdate.PreRender) UpdateMesh(keepRendererCount: true);
+			if (update == CanvasUpdate.PreRender) UpdateMeshToInstructions();
 			if (allowMultipleCanvasRenderers) canvasRenderer.Clear();
 			if (allowMultipleCanvasRenderers) canvasRenderer.Clear();
 		}
 		}
 
 
@@ -330,7 +330,8 @@ namespace Spine.Unity {
 			if (freeze) return;
 			if (freeze) return;
 			if (updateMode != UpdateMode.FullUpdate) return;
 			if (updateMode != UpdateMode.FullUpdate) return;
 
 
-			UpdateMesh();
+			PrepareInstructionsAndRenderers();
+			SetVerticesDirty(); // triggers Rebuild and avoids potential double-update in a single frame
 		}
 		}
 
 
 		protected void OnCullStateChanged (bool culled) {
 		protected void OnCullStateChanged (bool culled) {
@@ -574,16 +575,39 @@ namespace Spine.Unity {
 				OnRebuild(this);
 				OnRebuild(this);
 		}
 		}
 
 
-		public void UpdateMesh (bool keepRendererCount = false) {
-			if (!this.IsValid) return;
+		public void PrepareInstructionsAndRenderers () {
+			if (!this.allowMultipleCanvasRenderers) {
+				MeshGenerator.GenerateSingleSubmeshInstruction(currentInstructions, skeleton, null);
+				if (canvasRenderers.Count > 0)
+					DisableUnusedCanvasRenderers(usedCount: 0);
+				usedRenderersCount = 0;
+			} else {
+				MeshGenerator.GenerateSkeletonRendererInstruction(currentInstructions, skeleton, null,
+					enableSeparatorSlots ? separatorSlots : null,
+					enableSeparatorSlots ? separatorSlots.Count > 0 : false,
+					false);
+
+				int submeshCount = currentInstructions.submeshInstructions.Count;
+				EnsureCanvasRendererCount(submeshCount);
+				EnsureMeshesCount(submeshCount);
+				EnsureSeparatorPartCount();
+				PrepareRendererGameObjects(currentInstructions);
+			}
+		}
 
 
+		public void UpdateMesh () {
+			PrepareInstructionsAndRenderers();
+			UpdateMeshToInstructions();
+		}
+
+		public void UpdateMeshToInstructions () {
+			if (!this.IsValid || currentInstructions.rawVertexCount < 0) return;
 			skeleton.SetColor(this.color);
 			skeleton.SetColor(this.color);
 
 
-			var currentInstructions = this.currentInstructions;
 			if (!this.allowMultipleCanvasRenderers) {
 			if (!this.allowMultipleCanvasRenderers) {
-				UpdateMeshSingleCanvasRenderer();
+				UpdateMeshSingleCanvasRenderer(currentInstructions);
 			} else {
 			} else {
-				UpdateMeshMultipleCanvasRenderers(currentInstructions, keepRendererCount);
+				UpdateMeshMultipleCanvasRenderers(currentInstructions);
 			}
 			}
 
 
 			if (OnMeshAndMaterialsUpdated != null)
 			if (OnMeshAndMaterialsUpdated != null)
@@ -614,14 +638,9 @@ namespace Spine.Unity {
 			}
 			}
 		}
 		}
 
 
-		protected void UpdateMeshSingleCanvasRenderer () {
-			if (canvasRenderers.Count > 0)
-				DisableUnusedCanvasRenderers(usedCount: 0);
-
+		protected void UpdateMeshSingleCanvasRenderer (SkeletonRendererInstruction currentInstructions) {
 			var smartMesh = meshBuffers.GetNext();
 			var smartMesh = meshBuffers.GetNext();
-			MeshGenerator.GenerateSingleSubmeshInstruction(currentInstructions, skeleton, null);
 			bool updateTriangles = SkeletonRendererInstruction.GeometryNotEqual(currentInstructions, smartMesh.instructionUsed);
 			bool updateTriangles = SkeletonRendererInstruction.GeometryNotEqual(currentInstructions, smartMesh.instructionUsed);
-
 			meshGenerator.Begin();
 			meshGenerator.Begin();
 			if (currentInstructions.hasActiveClipping && currentInstructions.submeshInstructions.Count > 0) {
 			if (currentInstructions.hasActiveClipping && currentInstructions.submeshInstructions.Count > 0) {
 				meshGenerator.AddSubmesh(currentInstructions.submeshInstructions.Items[0], updateTriangles);
 				meshGenerator.AddSubmesh(currentInstructions.submeshInstructions.Items[0], updateTriangles);
@@ -650,37 +669,16 @@ namespace Spine.Unity {
 			}
 			}
 
 
 			//this.UpdateMaterial(); // note: This would allocate memory.
 			//this.UpdateMaterial(); // note: This would allocate memory.
-			usedRenderersCount = 0;
 		}
 		}
 
 
-		protected void UpdateMeshMultipleCanvasRenderers (SkeletonRendererInstruction currentInstructions, bool keepRendererCount) {
-			MeshGenerator.GenerateSkeletonRendererInstruction(currentInstructions, skeleton, null,
-				enableSeparatorSlots ? separatorSlots : null,
-				enableSeparatorSlots ? separatorSlots.Count > 0 : false,
-				false);
-
-			int submeshCount = currentInstructions.submeshInstructions.Count;
-			if (keepRendererCount && submeshCount != usedRenderersCount)
-				return;
-			EnsureCanvasRendererCount(submeshCount);
-			EnsureMeshesCount(submeshCount);
-			EnsureSeparatorPartCount();
-
+		protected void UpdateMeshMultipleCanvasRenderers (SkeletonRendererInstruction currentInstructions) {
 			var c = canvas;
 			var c = canvas;
 			float scale = (c == null) ? 100 : c.referencePixelsPerUnit;
 			float scale = (c == null) ? 100 : c.referencePixelsPerUnit;
 
 
 			// Generate meshes.
 			// Generate meshes.
+			int submeshCount = currentInstructions.submeshInstructions.Count;
 			var meshesItems = meshes.Items;
 			var meshesItems = meshes.Items;
 			bool useOriginalTextureAndMaterial = (customMaterialOverride.Count == 0 && customTextureOverride.Count == 0);
 			bool useOriginalTextureAndMaterial = (customMaterialOverride.Count == 0 && customTextureOverride.Count == 0);
-			int separatorSlotGroupIndex = 0;
-			Transform parent = this.separatorSlots.Count == 0 ? this.transform : this.separatorParts[0];
-
-			if (updateSeparatorPartLocation) {
-				for (int p = 0; p < this.separatorParts.Count; ++p) {
-					separatorParts[p].position = this.transform.position;
-					separatorParts[p].rotation = this.transform.rotation;
-				}
-			}
 
 
 			BlendModeMaterials blendModeMaterials = skeletonDataAsset.blendModeMaterials;
 			BlendModeMaterials blendModeMaterials = skeletonDataAsset.blendModeMaterials;
 			bool hasBlendModeMaterials = blendModeMaterials.RequiresBlendModeMaterials;
 			bool hasBlendModeMaterials = blendModeMaterials.RequiresBlendModeMaterials;
@@ -688,7 +686,6 @@ namespace Spine.Unity {
 			bool mainCullTransparentMesh = this.canvasRenderer.cullTransparentMesh;
 			bool mainCullTransparentMesh = this.canvasRenderer.cullTransparentMesh;
 #endif
 #endif
 			bool pmaVertexColors = meshGenerator.settings.pmaVertexColors;
 			bool pmaVertexColors = meshGenerator.settings.pmaVertexColors;
-			int targetSiblingIndex = 0;
 			for (int i = 0; i < submeshCount; i++) {
 			for (int i = 0; i < submeshCount; i++) {
 				var submeshInstructionItem = currentInstructions.submeshInstructions.Items[i];
 				var submeshInstructionItem = currentInstructions.submeshInstructions.Items[i];
 				meshGenerator.Begin();
 				meshGenerator.Begin();
@@ -703,22 +700,9 @@ namespace Spine.Unity {
 
 
 				var submeshMaterial = submeshInstructionItem.material;
 				var submeshMaterial = submeshInstructionItem.material;
 				var canvasRenderer = canvasRenderers[i];
 				var canvasRenderer = canvasRenderers[i];
-				if (i >= usedRenderersCount) {
-					canvasRenderer.gameObject.SetActive(true);
-				}
 				canvasRenderer.SetMesh(targetMesh);
 				canvasRenderer.SetMesh(targetMesh);
 				canvasRenderer.materialCount = 1;
 				canvasRenderer.materialCount = 1;
 
 
-				if (canvasRenderer.transform.parent != parent.transform) {
-					canvasRenderer.transform.SetParent(parent.transform, false);
-					canvasRenderer.transform.localPosition = Vector3.zero;
-				}
-				canvasRenderer.transform.SetSiblingIndex(targetSiblingIndex++);
-				if (submeshInstructionItem.forceSeparate) {
-					targetSiblingIndex = 0;
-					parent = separatorParts[++separatorSlotGroupIndex];
-				}
-
 				SkeletonSubmeshGraphic submeshGraphic = submeshGraphics[i];
 				SkeletonSubmeshGraphic submeshGraphic = submeshGraphics[i];
 				if (useOriginalTextureAndMaterial) {
 				if (useOriginalTextureAndMaterial) {
 					Texture usedTexture = submeshMaterial.mainTexture;
 					Texture usedTexture = submeshMaterial.mainTexture;
@@ -761,9 +745,6 @@ namespace Spine.Unity {
 					canvasRenderer.SetMaterial(usedMaterial, usedTexture);
 					canvasRenderer.SetMaterial(usedMaterial, usedTexture);
 				}
 				}
 			}
 			}
-
-			DisableUnusedCanvasRenderers(usedCount: submeshCount);
-			usedRenderersCount = submeshCount;
 		}
 		}
 
 
 		protected void EnsureCanvasRendererCount (int targetCount) {
 		protected void EnsureCanvasRendererCount (int targetCount) {
@@ -784,6 +765,40 @@ namespace Spine.Unity {
 			}
 			}
 		}
 		}
 
 
+		protected void PrepareRendererGameObjects (SkeletonRendererInstruction currentInstructions) {
+			int submeshCount = currentInstructions.submeshInstructions.Count;
+			DisableUnusedCanvasRenderers(usedCount: submeshCount);
+
+			int separatorSlotGroupIndex = 0;
+			int targetSiblingIndex = 0;
+			Transform parent = this.separatorSlots.Count == 0 ? this.transform : this.separatorParts[0];
+			if (updateSeparatorPartLocation) {
+				for (int p = 0; p < this.separatorParts.Count; ++p) {
+					separatorParts[p].position = this.transform.position;
+					separatorParts[p].rotation = this.transform.rotation;
+				}
+			}
+
+			for (int i = 0; i < submeshCount; i++) {
+				var canvasRenderer = canvasRenderers[i];
+				if (i >= usedRenderersCount) {
+					canvasRenderer.gameObject.SetActive(true);
+				}
+				if (canvasRenderer.transform.parent != parent.transform) {
+					canvasRenderer.transform.SetParent(parent.transform, false);
+					canvasRenderer.transform.localPosition = Vector3.zero;
+				}
+				canvasRenderer.transform.SetSiblingIndex(targetSiblingIndex++);
+
+				var submeshInstructionItem = currentInstructions.submeshInstructions.Items[i];
+				if (submeshInstructionItem.forceSeparate) {
+					targetSiblingIndex = 0;
+					parent = separatorParts[++separatorSlotGroupIndex];
+				}
+			}
+			usedRenderersCount = submeshCount;
+		}
+
 		protected void DisableUnusedCanvasRenderers (int usedCount) {
 		protected void DisableUnusedCanvasRenderers (int usedCount) {
 #if UNITY_EDITOR
 #if UNITY_EDITOR
 			RemoveNullCanvasRenderers();
 			RemoveNullCanvasRenderers();