mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-24 18:51:25 +08:00
reduce method calls overhead in SkeletonRenderer
reduce GC pressure in SkeletonAnimator
This commit is contained in:
parent
0635c19fef
commit
169ec15285
@ -139,12 +139,14 @@ namespace Spine {
|
|||||||
/// <summary>Updates the world transform for each bone and applies IK constraints.</summary>
|
/// <summary>Updates the world transform for each bone and applies IK constraints.</summary>
|
||||||
public void UpdateWorldTransform () {
|
public void UpdateWorldTransform () {
|
||||||
ExposedList<Bone> bones = this.bones;
|
ExposedList<Bone> bones = this.bones;
|
||||||
for (int ii = 0, nn = bones.Count; ii < nn; ii++) {
|
ExposedList<IkConstraint> ikConstraints = this.ikConstraints;
|
||||||
Bone bone = bones.Items[ii];
|
if (ikConstraints.Count > 0) {
|
||||||
bone.rotationIK = bone.rotation;
|
for (int ii = 0, nn = bones.Count; ii < nn; ii++) {
|
||||||
}
|
Bone bone = bones.Items[ii];
|
||||||
ExposedList<ExposedList<Bone>> boneCache = this.boneCache;
|
bone.rotationIK = bone.rotation;
|
||||||
ExposedList<IkConstraint> ikConstraints = this.ikConstraints;
|
}
|
||||||
|
}
|
||||||
|
ExposedList<ExposedList<Bone>> boneCache = this.boneCache;
|
||||||
int i = 0, last = boneCache.Count - 1;
|
int i = 0, last = boneCache.Count - 1;
|
||||||
while (true) {
|
while (true) {
|
||||||
ExposedList<Bone> updateBones = boneCache.Items[i];
|
ExposedList<Bone> updateBones = boneCache.Items[i];
|
||||||
|
|||||||
@ -63,6 +63,7 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation {
|
|||||||
protected event UpdateBonesDelegate _UpdateComplete;
|
protected event UpdateBonesDelegate _UpdateComplete;
|
||||||
|
|
||||||
Dictionary<string, Spine.Animation> animationTable = new Dictionary<string, Spine.Animation>();
|
Dictionary<string, Spine.Animation> animationTable = new Dictionary<string, Spine.Animation>();
|
||||||
|
Dictionary<AnimationClip, string> clipNameTable = new Dictionary<AnimationClip, string>();
|
||||||
Animator animator;
|
Animator animator;
|
||||||
|
|
||||||
public override void Reset () {
|
public override void Reset () {
|
||||||
@ -71,6 +72,7 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
animationTable.Clear();
|
animationTable.Clear();
|
||||||
|
clipNameTable.Clear();
|
||||||
|
|
||||||
var data = skeletonDataAsset.GetSkeletonData(true);
|
var data = skeletonDataAsset.GetSkeletonData(true);
|
||||||
|
|
||||||
@ -122,7 +124,7 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
float time = stateInfo.normalizedTime * info.clip.length;
|
float time = stateInfo.normalizedTime * info.clip.length;
|
||||||
animationTable[info.clip.name].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null, weight);
|
animationTable[GetAnimationClipName(info.clip)].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null, weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var info in nextClipInfo) {
|
foreach (var info in nextClipInfo) {
|
||||||
@ -131,7 +133,7 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
float time = nextStateInfo.normalizedTime * info.clip.length;
|
float time = nextStateInfo.normalizedTime * info.clip.length;
|
||||||
animationTable[info.clip.name].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null, weight);
|
animationTable[GetAnimationClipName(info.clip)].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null, weight);
|
||||||
}
|
}
|
||||||
} else if (mode >= MixMode.MixNext) {
|
} else if (mode >= MixMode.MixNext) {
|
||||||
//apply first non-zero weighted clip
|
//apply first non-zero weighted clip
|
||||||
@ -144,7 +146,7 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
float time = stateInfo.normalizedTime * info.clip.length;
|
float time = stateInfo.normalizedTime * info.clip.length;
|
||||||
animationTable[info.clip.name].Apply(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null);
|
animationTable[GetAnimationClipName(info.clip)].Apply(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,7 +158,7 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
float time = stateInfo.normalizedTime * info.clip.length;
|
float time = stateInfo.normalizedTime * info.clip.length;
|
||||||
animationTable[info.clip.name].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null, weight);
|
animationTable[GetAnimationClipName(info.clip)].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null, weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
c = 0;
|
c = 0;
|
||||||
@ -170,7 +172,7 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
float time = nextStateInfo.normalizedTime * info.clip.length;
|
float time = nextStateInfo.normalizedTime * info.clip.length;
|
||||||
animationTable[info.clip.name].Apply(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null);
|
animationTable[GetAnimationClipName(info.clip)].Apply(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -183,7 +185,7 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
float time = nextStateInfo.normalizedTime * info.clip.length;
|
float time = nextStateInfo.normalizedTime * info.clip.length;
|
||||||
animationTable[info.clip.name].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null, weight);
|
animationTable[GetAnimationClipName(info.clip)].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null, weight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -202,4 +204,14 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation {
|
|||||||
_UpdateComplete(this);
|
_UpdateComplete(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetAnimationClipName(AnimationClip clip) {
|
||||||
|
string clipName;
|
||||||
|
if (!clipNameTable.TryGetValue(clip, out clipName)) {
|
||||||
|
clipName = clip.name;
|
||||||
|
clipNameTable.Add(clip, clipName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return clipName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -173,8 +173,9 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
int submeshTriangleCount = 0, submeshFirstVertex = 0, submeshStartSlotIndex = 0;
|
int submeshTriangleCount = 0, submeshFirstVertex = 0, submeshStartSlotIndex = 0;
|
||||||
Material lastMaterial = null;
|
Material lastMaterial = null;
|
||||||
submeshMaterials.Clear();
|
submeshMaterials.Clear();
|
||||||
ExposedList<Slot> drawOrder = skeleton.DrawOrder;
|
ExposedList<Slot> drawOrder = skeleton.drawOrder;
|
||||||
int drawOrderCount = drawOrder.Count;
|
int drawOrderCount = drawOrder.Count;
|
||||||
|
int submeshSeparatorSlotsCount = submeshSeparatorSlots.Count;
|
||||||
bool renderMeshes = this.renderMeshes;
|
bool renderMeshes = this.renderMeshes;
|
||||||
for (int i = 0; i < drawOrderCount; i++) {
|
for (int i = 0; i < drawOrderCount; i++) {
|
||||||
Slot slot = drawOrder.Items[i];
|
Slot slot = drawOrder.Items[i];
|
||||||
@ -183,33 +184,34 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
object rendererObject;
|
object rendererObject;
|
||||||
int attachmentVertexCount, attachmentTriangleCount;
|
int attachmentVertexCount, attachmentTriangleCount;
|
||||||
|
|
||||||
if (attachment is RegionAttachment) {
|
RegionAttachment regionAttachment = attachment as RegionAttachment;
|
||||||
rendererObject = ((RegionAttachment)attachment).RendererObject;
|
if (regionAttachment != null) {
|
||||||
|
rendererObject = regionAttachment.RendererObject;
|
||||||
attachmentVertexCount = 4;
|
attachmentVertexCount = 4;
|
||||||
attachmentTriangleCount = 6;
|
attachmentTriangleCount = 6;
|
||||||
} else {
|
} else {
|
||||||
if (!renderMeshes)
|
if (!renderMeshes)
|
||||||
continue;
|
continue;
|
||||||
MeshAttachment meshAttachment = attachment as MeshAttachment;
|
MeshAttachment 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;
|
SkinnedMeshAttachment 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;
|
||||||
attachmentTriangleCount = skinnedMeshAttachment.triangles.Length;
|
attachmentTriangleCount = skinnedMeshAttachment.triangles.Length;
|
||||||
} else
|
} else
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populate submesh when material changes.
|
// Populate submesh when material changes.
|
||||||
Material material = (Material)((AtlasRegion)rendererObject).page.rendererObject;
|
Material material = (Material)((AtlasRegion)rendererObject).page.rendererObject;
|
||||||
|
if ((lastMaterial != null && lastMaterial.GetInstanceID() != material.GetInstanceID()) ||
|
||||||
if ((lastMaterial != material && lastMaterial != null) || submeshSeparatorSlots.Contains(slot)) {
|
(submeshSeparatorSlotsCount > 0 && submeshSeparatorSlots.Contains(slot))) {
|
||||||
AddSubmesh(lastMaterial, submeshStartSlotIndex, i, submeshTriangleCount, submeshFirstVertex, false);
|
AddSubmesh(lastMaterial, submeshStartSlotIndex, i, submeshTriangleCount, submeshFirstVertex, false);
|
||||||
submeshTriangleCount = 0;
|
submeshTriangleCount = 0;
|
||||||
submeshFirstVertex = vertexCount;
|
submeshFirstVertex = vertexCount;
|
||||||
@ -258,15 +260,23 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
for (int i = 0; i < drawOrderCount; i++) {
|
for (int i = 0; i < drawOrderCount; i++) {
|
||||||
Slot slot = drawOrder.Items[i];
|
Slot slot = drawOrder.Items[i];
|
||||||
Attachment attachment = slot.attachment;
|
Attachment attachment = slot.attachment;
|
||||||
if (attachment is RegionAttachment) {
|
RegionAttachment regionAttachment = attachment as RegionAttachment;
|
||||||
RegionAttachment regionAttachment = (RegionAttachment)attachment;
|
if (regionAttachment != null) {
|
||||||
regionAttachment.ComputeWorldVertices(slot.bone, tempVertices);
|
regionAttachment.ComputeWorldVertices(slot.bone, tempVertices);
|
||||||
|
|
||||||
float z = i * zSpacing;
|
float z = i * zSpacing;
|
||||||
vertices[vertexIndex] = new Vector3(tempVertices[RegionAttachment.X1], tempVertices[RegionAttachment.Y1], z);
|
vertices[vertexIndex].x = tempVertices[RegionAttachment.X1];
|
||||||
vertices[vertexIndex + 1] = new Vector3(tempVertices[RegionAttachment.X4], tempVertices[RegionAttachment.Y4], z);
|
vertices[vertexIndex].y = tempVertices[RegionAttachment.Y1];
|
||||||
vertices[vertexIndex + 2] = new Vector3(tempVertices[RegionAttachment.X2], tempVertices[RegionAttachment.Y2], z);
|
vertices[vertexIndex].z = z;
|
||||||
vertices[vertexIndex + 3] = new Vector3(tempVertices[RegionAttachment.X3], tempVertices[RegionAttachment.Y3], z);
|
vertices[vertexIndex + 1].x = tempVertices[RegionAttachment.X4];
|
||||||
|
vertices[vertexIndex + 1].y = tempVertices[RegionAttachment.Y4];
|
||||||
|
vertices[vertexIndex + 1].z = z;
|
||||||
|
vertices[vertexIndex + 2].x = tempVertices[RegionAttachment.X2];
|
||||||
|
vertices[vertexIndex + 2].y = tempVertices[RegionAttachment.Y2];
|
||||||
|
vertices[vertexIndex + 2].z = z;
|
||||||
|
vertices[vertexIndex + 3].x = tempVertices[RegionAttachment.X3];
|
||||||
|
vertices[vertexIndex + 3].y = tempVertices[RegionAttachment.Y3];
|
||||||
|
vertices[vertexIndex + 3].z = z;
|
||||||
|
|
||||||
color.a = (byte)(a * slot.a * regionAttachment.a);
|
color.a = (byte)(a * slot.a * regionAttachment.a);
|
||||||
color.r = (byte)(r * slot.r * regionAttachment.r * color.a);
|
color.r = (byte)(r * slot.r * regionAttachment.r * color.a);
|
||||||
@ -280,10 +290,14 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
colors[vertexIndex + 3] = color;
|
colors[vertexIndex + 3] = color;
|
||||||
|
|
||||||
float[] regionUVs = regionAttachment.uvs;
|
float[] regionUVs = regionAttachment.uvs;
|
||||||
uvs[vertexIndex] = new Vector2(regionUVs[RegionAttachment.X1], regionUVs[RegionAttachment.Y1]);
|
uvs[vertexIndex].x = regionUVs[RegionAttachment.X1];
|
||||||
uvs[vertexIndex + 1] = new Vector2(regionUVs[RegionAttachment.X4], regionUVs[RegionAttachment.Y4]);
|
uvs[vertexIndex].y = regionUVs[RegionAttachment.Y1];
|
||||||
uvs[vertexIndex + 2] = new Vector2(regionUVs[RegionAttachment.X2], regionUVs[RegionAttachment.Y2]);
|
uvs[vertexIndex + 1].x = regionUVs[RegionAttachment.X4];
|
||||||
uvs[vertexIndex + 3] = new Vector2(regionUVs[RegionAttachment.X3], regionUVs[RegionAttachment.Y3]);
|
uvs[vertexIndex + 1].y = regionUVs[RegionAttachment.Y4];
|
||||||
|
uvs[vertexIndex + 2].x = regionUVs[RegionAttachment.X2];
|
||||||
|
uvs[vertexIndex + 2].y = regionUVs[RegionAttachment.Y2];
|
||||||
|
uvs[vertexIndex + 3].x = regionUVs[RegionAttachment.X3];
|
||||||
|
uvs[vertexIndex + 3].y = regionUVs[RegionAttachment.Y3];
|
||||||
|
|
||||||
vertexIndex += 4;
|
vertexIndex += 4;
|
||||||
} else {
|
} else {
|
||||||
@ -306,9 +320,12 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
float[] meshUVs = meshAttachment.uvs;
|
float[] meshUVs = meshAttachment.uvs;
|
||||||
float z = i * zSpacing;
|
float z = i * zSpacing;
|
||||||
for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++) {
|
for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++) {
|
||||||
vertices[vertexIndex] = new Vector3(tempVertices[ii], tempVertices[ii + 1], z);
|
vertices[vertexIndex].x = tempVertices[ii];
|
||||||
|
vertices[vertexIndex].y = tempVertices[ii + 1];
|
||||||
|
vertices[vertexIndex].z = z;
|
||||||
colors[vertexIndex] = color;
|
colors[vertexIndex] = color;
|
||||||
uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
|
uvs[vertexIndex].x = meshUVs[ii];
|
||||||
|
uvs[vertexIndex].y = meshUVs[ii + 1];
|
||||||
}
|
}
|
||||||
} else if (attachment is SkinnedMeshAttachment) {
|
} else if (attachment is SkinnedMeshAttachment) {
|
||||||
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
||||||
@ -327,9 +344,12 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
float[] meshUVs = meshAttachment.uvs;
|
float[] meshUVs = meshAttachment.uvs;
|
||||||
float z = i * zSpacing;
|
float z = i * zSpacing;
|
||||||
for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++) {
|
for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++) {
|
||||||
vertices[vertexIndex] = new Vector3(tempVertices[ii], tempVertices[ii + 1], z);
|
vertices[vertexIndex].x = tempVertices[ii];
|
||||||
|
vertices[vertexIndex].y = tempVertices[ii + 1];
|
||||||
|
vertices[vertexIndex].z = z;
|
||||||
colors[vertexIndex] = color;
|
colors[vertexIndex] = color;
|
||||||
uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
|
uvs[vertexIndex].x = meshUVs[ii];
|
||||||
|
uvs[vertexIndex].y = meshUVs[ii + 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -420,7 +440,12 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
Slot slot = drawOrder.Items[i];
|
Slot slot = drawOrder.Items[i];
|
||||||
Attachment attachment = slot.attachment;
|
Attachment attachment = slot.attachment;
|
||||||
Bone bone = slot.bone;
|
Bone bone = slot.bone;
|
||||||
bool flip = frontFacing && ((bone.WorldFlipX != bone.WorldFlipY) != (Mathf.Sign(bone.WorldScaleX) != Mathf.Sign(bone.WorldScaleY)));
|
|
||||||
|
bool worldScaleXIsPositive = bone.worldScaleX >= 0f;
|
||||||
|
bool worldScaleYIsPositive = bone.worldScaleY >= 0f;
|
||||||
|
bool worldScaleIsSameSigns = (worldScaleXIsPositive && worldScaleYIsPositive) ||
|
||||||
|
(!worldScaleXIsPositive && !worldScaleYIsPositive);
|
||||||
|
bool flip = frontFacing && ((bone.worldFlipX != bone.worldFlipY) != worldScaleIsSameSigns);
|
||||||
|
|
||||||
if (attachment is RegionAttachment) {
|
if (attachment is RegionAttachment) {
|
||||||
if (!flip) {
|
if (!flip) {
|
||||||
@ -445,16 +470,18 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
}
|
}
|
||||||
int[] attachmentTriangles;
|
int[] attachmentTriangles;
|
||||||
int attachmentVertexCount;
|
int attachmentVertexCount;
|
||||||
if (attachment is MeshAttachment) {
|
MeshAttachment meshAttachment = attachment as MeshAttachment;
|
||||||
MeshAttachment meshAttachment = (MeshAttachment)attachment;
|
if (meshAttachment != null) {
|
||||||
attachmentVertexCount = meshAttachment.vertices.Length >> 1;
|
attachmentVertexCount = meshAttachment.vertices.Length >> 1;
|
||||||
attachmentTriangles = meshAttachment.triangles;
|
attachmentTriangles = meshAttachment.triangles;
|
||||||
} else if (attachment is SkinnedMeshAttachment) {
|
} else {
|
||||||
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
SkinnedMeshAttachment skinnedMeshAttachment = attachment as SkinnedMeshAttachment;
|
||||||
attachmentVertexCount = meshAttachment.uvs.Length >> 1;
|
if (skinnedMeshAttachment != null) {
|
||||||
attachmentTriangles = meshAttachment.triangles;
|
attachmentVertexCount = skinnedMeshAttachment.uvs.Length >> 1;
|
||||||
} else
|
attachmentTriangles = skinnedMeshAttachment.triangles;
|
||||||
continue;
|
} else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (flip) {
|
if (flip) {
|
||||||
for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii += 3, triangleIndex += 3) {
|
for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii += 3, triangleIndex += 3) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user