mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-28 04:31:27 +08:00
[Unity] Some ExposedList use optimization within loops.
This commit is contained in:
parent
83a7ecc3b0
commit
bfb58cbb19
@ -192,6 +192,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
int submeshTriangleCount = 0, submeshFirstVertex = 0, submeshStartSlotIndex = 0;
|
int submeshTriangleCount = 0, submeshFirstVertex = 0, submeshStartSlotIndex = 0;
|
||||||
Material lastMaterial = null;
|
Material lastMaterial = null;
|
||||||
ExposedList<Slot> drawOrder = skeleton.drawOrder;
|
ExposedList<Slot> drawOrder = skeleton.drawOrder;
|
||||||
|
var drawOrderItems = drawOrder.Items;
|
||||||
int drawOrderCount = drawOrder.Count;
|
int drawOrderCount = drawOrder.Count;
|
||||||
int submeshSeparatorSlotsCount = submeshSeparatorSlots.Count;
|
int submeshSeparatorSlotsCount = submeshSeparatorSlots.Count;
|
||||||
bool renderMeshes = this.renderMeshes;
|
bool renderMeshes = this.renderMeshes;
|
||||||
@ -199,22 +200,29 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
// Clear last state of attachments and submeshes
|
// Clear last state of attachments and submeshes
|
||||||
MeshState.SingleMeshState workingState = meshState.buffer;
|
MeshState.SingleMeshState workingState = meshState.buffer;
|
||||||
var workingAttachments = workingState.attachments;
|
var workingAttachments = workingState.attachments;
|
||||||
var workingFlips = workingState.attachmentsFlipState;
|
|
||||||
var workingSubmeshArguments = workingState.addSubmeshArguments;
|
|
||||||
workingAttachments.Clear(true);
|
workingAttachments.Clear(true);
|
||||||
workingState.UpdateAttachmentCount(drawOrderCount);
|
workingState.UpdateAttachmentCount(drawOrderCount);
|
||||||
|
var workingAttachmentsItems = workingAttachments.Items; // Make sure to not add to or remove from ExposedList inside the loop below
|
||||||
|
|
||||||
|
var workingFlips = workingState.attachmentsFlipState;
|
||||||
|
var workingFlipsItems = workingState.attachmentsFlipState.Items; // Make sure to not add to or remove from ExposedList inside the loop below
|
||||||
|
|
||||||
|
var workingSubmeshArguments = workingState.addSubmeshArguments; // Items array should not be cached. There is dynamic writing to this object.
|
||||||
workingSubmeshArguments.Clear(false);
|
workingSubmeshArguments.Clear(false);
|
||||||
|
|
||||||
MeshState.SingleMeshState storedState = useMesh1 ? meshState.stateMesh1 : meshState.stateMesh2;
|
MeshState.SingleMeshState storedState = useMesh1 ? meshState.stateMesh1 : meshState.stateMesh2;
|
||||||
var storedAttachments = storedState.attachments;
|
var storedAttachments = storedState.attachments;
|
||||||
var storedFlips = storedState.attachmentsFlipState;
|
var storedAttachmentsItems = storedAttachments.Items; // Make sure to not add to or remove from ExposedList inside the loop below
|
||||||
|
|
||||||
bool mustUpdateMeshStructure = storedState.requiresUpdate || // Force update if the mesh was cleared. (prevents flickering due to incorrect state)
|
var storedFlips = storedState.attachmentsFlipState;
|
||||||
|
var storedFlipsItems = storedFlips.Items; // Make sure to not add to or remove from ExposedList inside the loop below
|
||||||
|
|
||||||
|
bool mustUpdateMeshStructure = storedState.requiresUpdate || // Force update if the mesh was cleared. (prevents flickering due to incorrect state)
|
||||||
drawOrder.Count != storedAttachments.Count || // Number of slots changed (when does this happen?)
|
drawOrder.Count != storedAttachments.Count || // Number of slots changed (when does this happen?)
|
||||||
immutableTriangles != storedState.immutableTriangles; // Immutable Triangles flag changed.
|
immutableTriangles != storedState.immutableTriangles; // Immutable Triangles flag changed.
|
||||||
|
|
||||||
for (int i = 0; i < drawOrderCount; i++) {
|
for (int i = 0; i < drawOrderCount; i++) {
|
||||||
Slot slot = drawOrder.Items[i];
|
Slot slot = drawOrderItems[i];
|
||||||
Bone bone = slot.bone;
|
Bone bone = slot.bone;
|
||||||
Attachment attachment = slot.attachment;
|
Attachment attachment = slot.attachment;
|
||||||
|
|
||||||
@ -225,14 +233,14 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
bool worldScaleIsSameSigns = ((bone.worldScaleY >= 0f) == (bone.worldScaleX >= 0f));
|
bool worldScaleIsSameSigns = ((bone.worldScaleY >= 0f) == (bone.worldScaleX >= 0f));
|
||||||
bool flip = frontFacing && ((bone.worldFlipX != bone.worldFlipY) == worldScaleIsSameSigns); // TODO: bone flipX and flipY will be removed in Spine 3.0
|
bool flip = frontFacing && ((bone.worldFlipX != bone.worldFlipY) == worldScaleIsSameSigns); // TODO: bone flipX and flipY will be removed in Spine 3.0
|
||||||
|
|
||||||
workingFlips.Items[i] = flip;
|
workingFlipsItems[i] = flip;
|
||||||
workingAttachments.Items[i] = attachment;
|
workingAttachmentsItems[i] = attachment;
|
||||||
|
|
||||||
mustUpdateMeshStructure = mustUpdateMeshStructure || // Always prefer short circuited or. || and not |=.
|
mustUpdateMeshStructure = mustUpdateMeshStructure || // Always prefer short circuited or. || and not |=.
|
||||||
(attachment != storedAttachments.Items[i]) || // Attachment order changed. // This relies on the drawOrder.Count != storedAttachments.Count check above as a bounds check.
|
(attachment != storedAttachmentsItems[i]) || // Attachment order changed. // This relies on the drawOrder.Count != storedAttachments.Count check above as a bounds check.
|
||||||
(flip != storedFlips.Items[i]); // Flip states changed.
|
(flip != storedFlipsItems[i]); // Flip states changed.
|
||||||
|
|
||||||
RegionAttachment regionAttachment = attachment as RegionAttachment;
|
var regionAttachment = attachment as RegionAttachment;
|
||||||
if (regionAttachment != null) {
|
if (regionAttachment != null) {
|
||||||
rendererObject = regionAttachment.RendererObject;
|
rendererObject = regionAttachment.RendererObject;
|
||||||
attachmentVertexCount = 4;
|
attachmentVertexCount = 4;
|
||||||
@ -240,13 +248,13 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
} else {
|
} else {
|
||||||
if (!renderMeshes)
|
if (!renderMeshes)
|
||||||
continue;
|
continue;
|
||||||
MeshAttachment meshAttachment = attachment as MeshAttachment;
|
var meshAttachment = attachment as MeshAttachment;
|
||||||
if (meshAttachment != null) {
|
if (meshAttachment != null) {
|
||||||
rendererObject = meshAttachment.RendererObject;
|
rendererObject = meshAttachment.RendererObject;
|
||||||
attachmentVertexCount = meshAttachment.vertices.Length >> 1;
|
attachmentVertexCount = meshAttachment.vertices.Length >> 1;
|
||||||
attachmentTriangleCount = meshAttachment.triangles.Length;
|
attachmentTriangleCount = meshAttachment.triangles.Length;
|
||||||
} else {
|
} else {
|
||||||
SkinnedMeshAttachment skinnedMeshAttachment = attachment as SkinnedMeshAttachment;
|
var skinnedMeshAttachment = attachment as SkinnedMeshAttachment;
|
||||||
if (skinnedMeshAttachment != null) {
|
if (skinnedMeshAttachment != null) {
|
||||||
rendererObject = skinnedMeshAttachment.RendererObject;
|
rendererObject = skinnedMeshAttachment.RendererObject;
|
||||||
attachmentVertexCount = skinnedMeshAttachment.uvs.Length >> 1;
|
attachmentVertexCount = skinnedMeshAttachment.uvs.Length >> 1;
|
||||||
@ -301,7 +309,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
|
|
||||||
mustUpdateMeshStructure = mustUpdateMeshStructure ||
|
mustUpdateMeshStructure = mustUpdateMeshStructure ||
|
||||||
this.sharedMaterials.Length != workingSubmeshArguments.Count || // Material array changed in size
|
this.sharedMaterials.Length != workingSubmeshArguments.Count || // Material array changed in size
|
||||||
CheckIfMustUpdateMeshStructure(workingSubmeshArguments); // Submesh Argument Array changed.
|
CheckIfMustUpdateMeshStructure(workingSubmeshArguments); // Submesh Argument Array changed.
|
||||||
|
|
||||||
// CheckIfMustUpdateMaterialArray (workingMaterials, sharedMaterials)
|
// CheckIfMustUpdateMaterialArray (workingMaterials, sharedMaterials)
|
||||||
if (!mustUpdateMeshStructure) {
|
if (!mustUpdateMeshStructure) {
|
||||||
@ -319,8 +327,10 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
|
|
||||||
if (mustUpdateMeshStructure) {
|
if (mustUpdateMeshStructure) {
|
||||||
this.submeshMaterials.Clear();
|
this.submeshMaterials.Clear();
|
||||||
|
|
||||||
|
var workingSubmeshArgumentsItems = workingSubmeshArguments.Items;
|
||||||
for (int i = 0, n = workingSubmeshArguments.Count; i < n; i++) {
|
for (int i = 0, n = workingSubmeshArguments.Count; i < n; i++) {
|
||||||
AddSubmesh(workingSubmeshArguments.Items[i], workingFlips);
|
AddSubmesh(workingSubmeshArgumentsItems[i], workingFlips);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set materials.
|
// Set materials.
|
||||||
@ -383,7 +393,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
}
|
}
|
||||||
int i = 0;
|
int i = 0;
|
||||||
do {
|
do {
|
||||||
Slot slot = drawOrder.Items[i];
|
Slot slot = drawOrderItems[i];
|
||||||
Attachment attachment = slot.attachment;
|
Attachment attachment = slot.attachment;
|
||||||
RegionAttachment regionAttachment = attachment as RegionAttachment;
|
RegionAttachment regionAttachment = attachment as RegionAttachment;
|
||||||
if (regionAttachment != null) {
|
if (regionAttachment != null) {
|
||||||
@ -636,7 +646,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddSubmesh (MeshState.AddSubmeshArguments submeshArguments, ExposedList<bool> flipStates) {
|
private void AddSubmesh (MeshState.AddSubmeshArguments submeshArguments, ExposedList<bool> flipStates) { //submeshArguments is a struct, so it's ok.
|
||||||
int submeshIndex = submeshMaterials.Count;
|
int submeshIndex = submeshMaterials.Count;
|
||||||
submeshMaterials.Add(submeshArguments.material);
|
submeshMaterials.Add(submeshArguments.material);
|
||||||
|
|
||||||
@ -645,8 +655,8 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
else if (immutableTriangles)
|
else if (immutableTriangles)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Submesh submesh = submeshes.Items[submeshIndex];
|
Submesh currentSubmesh = submeshes.Items[submeshIndex];
|
||||||
int[] triangles = submesh.triangles;
|
int[] triangles = currentSubmesh.triangles;
|
||||||
|
|
||||||
int triangleCount = submeshArguments.triangleCount;
|
int triangleCount = submeshArguments.triangleCount;
|
||||||
int firstVertex = submeshArguments.firstVertex;
|
int firstVertex = submeshArguments.firstVertex;
|
||||||
@ -654,22 +664,24 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
int trianglesCapacity = triangles.Length;
|
int trianglesCapacity = triangles.Length;
|
||||||
if (submeshArguments.isLastSubmesh && trianglesCapacity > triangleCount) {
|
if (submeshArguments.isLastSubmesh && trianglesCapacity > triangleCount) {
|
||||||
// Last submesh may have more triangles than required, so zero triangles to the end.
|
// Last submesh may have more triangles than required, so zero triangles to the end.
|
||||||
for (int i = triangleCount; i < trianglesCapacity; i++)
|
for (int i = triangleCount; i < trianglesCapacity; i++) {
|
||||||
triangles[i] = 0;
|
triangles[i] = 0;
|
||||||
submesh.triangleCount = triangleCount;
|
}
|
||||||
|
currentSubmesh.triangleCount = triangleCount;
|
||||||
|
|
||||||
} else if (trianglesCapacity != triangleCount) {
|
} else if (trianglesCapacity != triangleCount) {
|
||||||
// Reallocate triangles when not the exact size needed.
|
// Reallocate triangles when not the exact size needed.
|
||||||
submesh.triangles = triangles = new int[triangleCount];
|
currentSubmesh.triangles = triangles = new int[triangleCount];
|
||||||
submesh.triangleCount = 0;
|
currentSubmesh.triangleCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!renderMeshes && !frontFacing) {
|
if (!this.renderMeshes && !this.frontFacing) {
|
||||||
// Use stored triangles if possible.
|
// Use stored triangles if possible.
|
||||||
if (submesh.firstVertex != firstVertex || submesh.triangleCount < triangleCount) {
|
if (currentSubmesh.firstVertex != firstVertex || currentSubmesh.triangleCount < triangleCount) { //|| currentSubmesh.triangleCount == 0
|
||||||
submesh.triangleCount = triangleCount;
|
currentSubmesh.triangleCount = triangleCount;
|
||||||
submesh.firstVertex = firstVertex;
|
currentSubmesh.firstVertex = firstVertex;
|
||||||
//int drawOrderIndex = 0;
|
|
||||||
for (int i = 0; i < triangleCount; i += 6, firstVertex += 4/*, drawOrderIndex++*/) {
|
for (int i = 0; i < triangleCount; i += 6, firstVertex += 4) {
|
||||||
triangles[i] = firstVertex;
|
triangles[i] = firstVertex;
|
||||||
triangles[i + 1] = firstVertex + 2;
|
triangles[i + 1] = firstVertex + 2;
|
||||||
triangles[i + 2] = firstVertex + 1;
|
triangles[i + 2] = firstVertex + 1;
|
||||||
@ -677,18 +689,21 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
triangles[i + 4] = firstVertex + 3;
|
triangles[i + 4] = firstVertex + 3;
|
||||||
triangles[i + 5] = firstVertex + 1;
|
triangles[i + 5] = firstVertex + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate through all slots and store their triangles.
|
// Iterate through all slots and store their triangles.
|
||||||
ExposedList<Slot> drawOrder = skeleton.DrawOrder;
|
|
||||||
|
var drawOrderItems = skeleton.DrawOrder.Items; // Make sure to not modify ExposedList inside the loop below
|
||||||
|
var flipStatesItems = flipStates.Items; // Make sure to not modify ExposedList inside the loop below
|
||||||
|
|
||||||
int triangleIndex = 0; // Modified by loop
|
int triangleIndex = 0; // Modified by loop
|
||||||
for (int i = submeshArguments.startSlot, n = submeshArguments.endSlot; i < n; i++) {
|
for (int i = submeshArguments.startSlot, n = submeshArguments.endSlot; i < n; i++) {
|
||||||
Slot slot = drawOrder.Items[i];
|
Attachment attachment = drawOrderItems[i].attachment;
|
||||||
Attachment attachment = slot.attachment;
|
|
||||||
|
|
||||||
bool flip = flipStates.Items[i];
|
bool flip = flipStatesItems[i];
|
||||||
|
|
||||||
// Add RegionAttachment triangles
|
// Add RegionAttachment triangles
|
||||||
if (attachment is RegionAttachment) {
|
if (attachment is RegionAttachment) {
|
||||||
@ -716,12 +731,12 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
// Add (Skinned)MeshAttachment triangles
|
// Add (Skinned)MeshAttachment triangles
|
||||||
int[] attachmentTriangles;
|
int[] attachmentTriangles;
|
||||||
int attachmentVertexCount;
|
int attachmentVertexCount;
|
||||||
MeshAttachment meshAttachment = attachment as MeshAttachment;
|
var meshAttachment = attachment as MeshAttachment;
|
||||||
if (meshAttachment != null) {
|
if (meshAttachment != null) {
|
||||||
attachmentVertexCount = meshAttachment.vertices.Length >> 1; // length/2
|
attachmentVertexCount = meshAttachment.vertices.Length >> 1; // length/2
|
||||||
attachmentTriangles = meshAttachment.triangles;
|
attachmentTriangles = meshAttachment.triangles;
|
||||||
} else {
|
} else {
|
||||||
SkinnedMeshAttachment skinnedMeshAttachment = attachment as SkinnedMeshAttachment;
|
var skinnedMeshAttachment = attachment as SkinnedMeshAttachment;
|
||||||
if (skinnedMeshAttachment != null) {
|
if (skinnedMeshAttachment != null) {
|
||||||
attachmentVertexCount = skinnedMeshAttachment.uvs.Length >> 1; // length/2
|
attachmentVertexCount = skinnedMeshAttachment.uvs.Length >> 1; // length/2
|
||||||
attachmentTriangles = skinnedMeshAttachment.triangles;
|
attachmentTriangles = skinnedMeshAttachment.triangles;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user