mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
[unity] Fixed SkeletonGraphic unnecessary redundant mesh update at color change. Changed update code to use SetVerticesDirty and Rebuild. Closes #2049.
This commit is contained in:
parent
8761f44aa7
commit
c5df7b7bdb
@ -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) {
|
public void PrepareInstructionsAndRenderers () {
|
||||||
if (!this.IsValid) return;
|
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 () {
|
protected void UpdateMeshSingleCanvasRenderer (SkeletonRendererInstruction currentInstructions) {
|
||||||
if (canvasRenderers.Count > 0)
|
|
||||||
DisableUnusedCanvasRenderers(usedCount: 0);
|
|
||||||
|
|
||||||
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) {
|
protected void UpdateMeshMultipleCanvasRenderers (SkeletonRendererInstruction currentInstructions) {
|
||||||
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();
|
|
||||||
|
|
||||||
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();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user