Merge pull request #483 from LostPolygon/optimization-fix

[Spine-Unity] Fix #481
This commit is contained in:
John 2015-12-15 16:13:37 +08:00
commit a43c849dfe

View File

@ -71,7 +71,7 @@ public class SkeletonRenderer : MonoBehaviour {
private readonly ExposedList<Material> submeshMaterials = new ExposedList<Material>(); private readonly ExposedList<Material> submeshMaterials = new ExposedList<Material>();
private readonly ExposedList<Submesh> submeshes = new ExposedList<Submesh>(); private readonly ExposedList<Submesh> submeshes = new ExposedList<Submesh>();
private SkeletonUtilitySubmeshRenderer[] submeshRenderers; private SkeletonUtilitySubmeshRenderer[] submeshRenderers;
private LastState lastState = new LastState(); private MeshState meshState = new MeshState();
public virtual void Reset () { public virtual void Reset () {
if (meshFilter != null) if (meshFilter != null)
@ -94,7 +94,7 @@ public class SkeletonRenderer : MonoBehaviour {
DestroyImmediate(mesh2); DestroyImmediate(mesh2);
} }
lastState = new LastState(); meshState = new MeshState();
mesh1 = null; mesh1 = null;
mesh2 = null; mesh2 = null;
vertices = null; vertices = null;
@ -193,15 +193,11 @@ public class SkeletonRenderer : MonoBehaviour {
bool renderMeshes = this.renderMeshes; bool renderMeshes = this.renderMeshes;
// Clear last state of attachments and submeshes // Clear last state of attachments and submeshes
ExposedList<int> attachmentsTriangleCountTemp = lastState.attachmentsTriangleCountTemp; MeshState.SingleMeshState stateTemp = meshState.stateTemp;
attachmentsTriangleCountTemp.GrowIfNeeded(drawOrderCount); stateTemp.attachments.Clear(true);
attachmentsTriangleCountTemp.Count = drawOrderCount; stateTemp.UpdateDrawOrderCount(drawOrderCount);
ExposedList<bool> attachmentsFlipStateTemp = lastState.attachmentsFlipStateTemp;
attachmentsFlipStateTemp.GrowIfNeeded(drawOrderCount);
attachmentsFlipStateTemp.Count = drawOrderCount;
ExposedList<LastState.AddSubmeshArguments> addSubmeshArgumentsTemp = lastState.addSubmeshArgumentsTemp; stateTemp.addSubmeshArguments.Clear(false);
addSubmeshArgumentsTemp.Clear(false);
for (int i = 0; i < drawOrderCount; i++) { for (int i = 0; i < drawOrderCount; i++) {
Slot slot = drawOrder.Items[i]; Slot slot = drawOrder.Items[i];
Bone bone = slot.bone; Bone bone = slot.bone;
@ -214,9 +210,9 @@ public class SkeletonRenderer : MonoBehaviour {
bool worldScaleIsSameSigns = (worldScaleXIsPositive && worldScaleYIsPositive) || bool worldScaleIsSameSigns = (worldScaleXIsPositive && worldScaleYIsPositive) ||
(!worldScaleXIsPositive && !worldScaleYIsPositive); (!worldScaleXIsPositive && !worldScaleYIsPositive);
bool flip = frontFacing && ((bone.worldFlipX != bone.worldFlipY) == worldScaleIsSameSigns); bool flip = frontFacing && ((bone.worldFlipX != bone.worldFlipY) == worldScaleIsSameSigns);
attachmentsFlipStateTemp.Items[i] = flip; stateTemp.attachmentsFlipState.Items[i] = flip;
attachmentsTriangleCountTemp.Items[i] = -1; stateTemp.attachments.Items[i] = attachment;
RegionAttachment regionAttachment = attachment as RegionAttachment; RegionAttachment regionAttachment = attachment as RegionAttachment;
if (regionAttachment != null) { if (regionAttachment != null) {
rendererObject = regionAttachment.RendererObject; rendererObject = regionAttachment.RendererObject;
@ -249,8 +245,8 @@ public class SkeletonRenderer : MonoBehaviour {
#endif #endif
if ((lastMaterial != null && lastMaterial.GetInstanceID() != material.GetInstanceID()) || if ((lastMaterial != null && lastMaterial.GetInstanceID() != material.GetInstanceID()) ||
(submeshSeparatorSlotsCount > 0 && submeshSeparatorSlots.Contains(slot))) { (submeshSeparatorSlotsCount > 0 && submeshSeparatorSlots.Contains(slot))) {
addSubmeshArgumentsTemp.Add( stateTemp.addSubmeshArguments.Add(
new LastState.AddSubmeshArguments(lastMaterial, submeshStartSlotIndex, i, submeshTriangleCount, submeshFirstVertex, false) new MeshState.AddSubmeshArguments(lastMaterial, submeshStartSlotIndex, i, submeshTriangleCount, submeshFirstVertex, false)
); );
submeshTriangleCount = 0; submeshTriangleCount = 0;
submeshFirstVertex = vertexCount; submeshFirstVertex = vertexCount;
@ -260,18 +256,16 @@ public class SkeletonRenderer : MonoBehaviour {
submeshTriangleCount += attachmentTriangleCount; submeshTriangleCount += attachmentTriangleCount;
vertexCount += attachmentVertexCount; vertexCount += attachmentVertexCount;
attachmentsTriangleCountTemp.Items[i] = attachmentTriangleCount;
} }
addSubmeshArgumentsTemp.Add( stateTemp.addSubmeshArguments.Add(
new LastState.AddSubmeshArguments(lastMaterial, submeshStartSlotIndex, drawOrderCount, submeshTriangleCount, submeshFirstVertex, true) new MeshState.AddSubmeshArguments(lastMaterial, submeshStartSlotIndex, drawOrderCount, submeshTriangleCount, submeshFirstVertex, true)
); );
bool mustUpdateMeshStructure = CheckIfMustUpdateMeshStructure(attachmentsTriangleCountTemp, attachmentsFlipStateTemp, addSubmeshArgumentsTemp); bool mustUpdateMeshStructure = CheckIfMustUpdateMeshStructure(stateTemp.attachments, stateTemp.attachmentsFlipState, stateTemp.addSubmeshArguments);
if (mustUpdateMeshStructure) { if (mustUpdateMeshStructure) {
submeshMaterials.Clear(); submeshMaterials.Clear();
for (int i = 0, n = addSubmeshArgumentsTemp.Count; i < n; i++) { for (int i = 0, n = stateTemp.addSubmeshArguments.Count; i < n; i++) {
LastState.AddSubmeshArguments arguments = addSubmeshArgumentsTemp.Items[i]; MeshState.AddSubmeshArguments arguments = stateTemp.addSubmeshArguments.Items[i];
AddSubmesh( AddSubmesh(
arguments.material, arguments.material,
arguments.startSlot, arguments.startSlot,
@ -279,7 +273,7 @@ public class SkeletonRenderer : MonoBehaviour {
arguments.triangleCount, arguments.triangleCount,
arguments.firstVertex, arguments.firstVertex,
arguments.lastSubmesh, arguments.lastSubmesh,
attachmentsFlipStateTemp stateTemp.attachmentsFlipState
); );
} }
@ -305,10 +299,10 @@ public class SkeletonRenderer : MonoBehaviour {
} else { } else {
// Too many vertices, zero the extra. // Too many vertices, zero the extra.
Vector3 zero = Vector3.zero; Vector3 zero = Vector3.zero;
for (int i = vertexCount, n = lastState.vertexCount; i < n; i++) for (int i = vertexCount, n = meshState.vertexCount; i < n; i++)
vertices[i] = zero; vertices[i] = zero;
} }
lastState.vertexCount = vertexCount; meshState.vertexCount = vertexCount;
// Setup mesh. // Setup mesh.
float zSpacing = this.zSpacing; float zSpacing = this.zSpacing;
@ -534,32 +528,21 @@ public class SkeletonRenderer : MonoBehaviour {
} }
// Update previous state // Update previous state
ExposedList<int> attachmentsTriangleCountCurrentMesh; MeshState.SingleMeshState currentMeshState = useMesh1 ? meshState.stateMesh1 : meshState.stateMesh2;
ExposedList<bool> attachmentsFlipStateCurrentMesh; currentMeshState.immutableTriangles = immutableTriangles;
ExposedList<LastState.AddSubmeshArguments> addSubmeshArgumentsCurrentMesh;
if (useMesh1) {
attachmentsTriangleCountCurrentMesh = lastState.attachmentsTriangleCountMesh1;
addSubmeshArgumentsCurrentMesh = lastState.addSubmeshArgumentsMesh1;
attachmentsFlipStateCurrentMesh = lastState.attachmentsFlipStateMesh1;
lastState.immutableTrianglesMesh1 = immutableTriangles;
} else {
attachmentsTriangleCountCurrentMesh = lastState.attachmentsTriangleCountMesh2;
addSubmeshArgumentsCurrentMesh = lastState.addSubmeshArgumentsMesh2;
attachmentsFlipStateCurrentMesh = lastState.attachmentsFlipStateMesh2;
lastState.immutableTrianglesMesh2 = immutableTriangles;
}
attachmentsTriangleCountCurrentMesh.GrowIfNeeded(attachmentsTriangleCountTemp.Capacity); currentMeshState.attachments.Clear(true);
attachmentsTriangleCountCurrentMesh.Count = attachmentsTriangleCountTemp.Count; currentMeshState.attachments.GrowIfNeeded(stateTemp.attachments.Capacity);
attachmentsTriangleCountTemp.CopyTo(attachmentsTriangleCountCurrentMesh.Items, 0); currentMeshState.attachments.Count = stateTemp.attachments.Count;
stateTemp.attachments.CopyTo(currentMeshState.attachments.Items);
attachmentsFlipStateCurrentMesh.GrowIfNeeded(attachmentsFlipStateTemp.Capacity); currentMeshState.attachmentsFlipState.GrowIfNeeded(stateTemp.attachmentsFlipState.Capacity);
attachmentsFlipStateCurrentMesh.Count = attachmentsFlipStateTemp.Count; currentMeshState.attachmentsFlipState.Count = stateTemp.attachmentsFlipState.Count;
attachmentsFlipStateTemp.CopyTo(attachmentsFlipStateCurrentMesh.Items, 0); stateTemp.attachmentsFlipState.CopyTo(currentMeshState.attachmentsFlipState.Items);
addSubmeshArgumentsCurrentMesh.GrowIfNeeded(addSubmeshArgumentsTemp.Count); currentMeshState.addSubmeshArguments.GrowIfNeeded(stateTemp.addSubmeshArguments.Capacity);
addSubmeshArgumentsCurrentMesh.Count = addSubmeshArgumentsTemp.Count; currentMeshState.addSubmeshArguments.Count = stateTemp.addSubmeshArguments.Count;
addSubmeshArgumentsTemp.CopyTo(addSubmeshArgumentsCurrentMesh.Items); stateTemp.addSubmeshArguments.CopyTo(currentMeshState.addSubmeshArguments.Items);
if (submeshRenderers.Length > 0) { if (submeshRenderers.Length > 0) {
for (int i = 0; i < submeshRenderers.Length; i++) { for (int i = 0; i < submeshRenderers.Length; i++) {
@ -575,39 +558,33 @@ public class SkeletonRenderer : MonoBehaviour {
useMesh1 = !useMesh1; useMesh1 = !useMesh1;
} }
private bool CheckIfMustUpdateMeshStructure (ExposedList<int> attachmentsTriangleCountTemp, ExposedList<bool> attachmentsFlipStateTemp, ExposedList<LastState.AddSubmeshArguments> addSubmeshArgumentsTemp) { private bool CheckIfMustUpdateMeshStructure (ExposedList<Attachment> attachmentsTemp, ExposedList<bool> attachmentsFlipStateTemp, ExposedList<MeshState.AddSubmeshArguments> addSubmeshArgumentsTemp) {
#if UNITY_EDITOR
if (!Application.isPlaying)
return true;
#endif
// Check if any mesh settings were changed // Check if any mesh settings were changed
bool mustUpdateMeshStructure = bool mustUpdateMeshStructure =
immutableTriangles != (useMesh1 ? lastState.immutableTrianglesMesh1 : lastState.immutableTrianglesMesh2); immutableTriangles != (useMesh1 ? meshState.stateMesh1.immutableTriangles : meshState.stateMesh2.immutableTriangles);
#if UNITY_EDITOR
mustUpdateMeshStructure |= !Application.isPlaying;
#endif
if (mustUpdateMeshStructure) if (mustUpdateMeshStructure)
return true; return true;
// Check if any attachments were enabled/disabled // Check if any attachments were enabled/disabled
// or submesh structures has changed // or submesh structures has changed
ExposedList<int> attachmentsTriangleCountCurrentMesh; MeshState.SingleMeshState currentMeshState = useMesh1 ? meshState.stateMesh1 : meshState.stateMesh2;
ExposedList<bool> attachmentsFlipStateCurrentMesh; ExposedList<Attachment> attachmentsCurrentMesh = currentMeshState.attachments;
ExposedList<LastState.AddSubmeshArguments> addSubmeshArgumentsCurrentMesh; ExposedList<MeshState.AddSubmeshArguments> addSubmeshArgumentsCurrentMesh = currentMeshState.addSubmeshArguments;
if (useMesh1) { ExposedList<bool> attachmentsFlipStateCurrentMesh = currentMeshState.attachmentsFlipState;
attachmentsTriangleCountCurrentMesh = lastState.attachmentsTriangleCountMesh1;
addSubmeshArgumentsCurrentMesh = lastState.addSubmeshArgumentsMesh1;
attachmentsFlipStateCurrentMesh = lastState.attachmentsFlipStateMesh1;
} else {
attachmentsTriangleCountCurrentMesh = lastState.attachmentsTriangleCountMesh2;
addSubmeshArgumentsCurrentMesh = lastState.addSubmeshArgumentsMesh2;
attachmentsFlipStateCurrentMesh = lastState.attachmentsFlipStateMesh2;
}
// Check attachments // Check attachments
int attachmentCount = attachmentsTriangleCountTemp.Count; int attachmentCount = attachmentsTemp.Count;
if (attachmentsTriangleCountCurrentMesh.Count != attachmentCount) if (attachmentsCurrentMesh.Count != attachmentCount)
return true; return true;
for (int i = 0; i < attachmentCount; i++) { for (int i = 0; i < attachmentCount; i++) {
if (attachmentsTriangleCountCurrentMesh.Items[i] != attachmentsTriangleCountTemp.Items[i]) if (attachmentsCurrentMesh.Items[i] != attachmentsTemp.Items[i])
return true; return true;
} }
@ -749,19 +726,26 @@ public class SkeletonRenderer : MonoBehaviour {
} }
#endif #endif
private class LastState { private class MeshState {
public bool immutableTrianglesMesh1;
public bool immutableTrianglesMesh2;
public int vertexCount; public int vertexCount;
public readonly ExposedList<bool> attachmentsFlipStateTemp = new ExposedList<bool>(); public readonly SingleMeshState stateTemp = new SingleMeshState();
public readonly ExposedList<bool> attachmentsFlipStateMesh1 = new ExposedList<bool>(); public readonly SingleMeshState stateMesh1 = new SingleMeshState();
public readonly ExposedList<bool> attachmentsFlipStateMesh2 = new ExposedList<bool>(); public readonly SingleMeshState stateMesh2 = new SingleMeshState();
public readonly ExposedList<int> attachmentsTriangleCountTemp = new ExposedList<int>();
public readonly ExposedList<int> attachmentsTriangleCountMesh1 = new ExposedList<int>(); public class SingleMeshState {
public readonly ExposedList<int> attachmentsTriangleCountMesh2 = new ExposedList<int>(); public bool immutableTriangles;
public readonly ExposedList<AddSubmeshArguments> addSubmeshArgumentsTemp = new ExposedList<AddSubmeshArguments>(); public readonly ExposedList<Attachment> attachments = new ExposedList<Attachment>();
public readonly ExposedList<AddSubmeshArguments> addSubmeshArgumentsMesh1 = new ExposedList<AddSubmeshArguments>(); public readonly ExposedList<bool> attachmentsFlipState = new ExposedList<bool>();
public readonly ExposedList<AddSubmeshArguments> addSubmeshArgumentsMesh2 = new ExposedList<AddSubmeshArguments>(); public readonly ExposedList<AddSubmeshArguments> addSubmeshArguments = new ExposedList<AddSubmeshArguments>();
public void UpdateDrawOrderCount(int drawOrderCount) {
attachmentsFlipState.GrowIfNeeded(drawOrderCount);
attachmentsFlipState.Count = drawOrderCount;
attachments.GrowIfNeeded(drawOrderCount);
attachments.Count = drawOrderCount;
}
}
public struct AddSubmeshArguments { public struct AddSubmeshArguments {
public Material material; public Material material;