mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
Merge pull request #351 from Fenrisul/master
Null mesh cleanup fixed in SkeletonRenderer
This commit is contained in:
commit
5275e921c8
@ -33,7 +33,7 @@ using UnityEngine;
|
|||||||
|
|
||||||
[CustomEditor(typeof(SkeletonRenderer))]
|
[CustomEditor(typeof(SkeletonRenderer))]
|
||||||
public class SkeletonRendererInspector : Editor {
|
public class SkeletonRendererInspector : Editor {
|
||||||
protected SerializedProperty skeletonDataAsset, initialSkinName, normals, tangents, meshes, immutableTriangles, submeshSeparators;
|
protected SerializedProperty skeletonDataAsset, initialSkinName, normals, tangents, meshes, immutableTriangles, submeshSeparators, front;
|
||||||
|
|
||||||
protected virtual void OnEnable () {
|
protected virtual void OnEnable () {
|
||||||
SpineEditorUtilities.ConfirmInitialization();
|
SpineEditorUtilities.ConfirmInitialization();
|
||||||
@ -44,6 +44,7 @@ public class SkeletonRendererInspector : Editor {
|
|||||||
meshes = serializedObject.FindProperty("renderMeshes");
|
meshes = serializedObject.FindProperty("renderMeshes");
|
||||||
immutableTriangles = serializedObject.FindProperty("immutableTriangles");
|
immutableTriangles = serializedObject.FindProperty("immutableTriangles");
|
||||||
submeshSeparators = serializedObject.FindProperty("submeshSeparators");
|
submeshSeparators = serializedObject.FindProperty("submeshSeparators");
|
||||||
|
front = serializedObject.FindProperty("frontFacing");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void gui () {
|
protected virtual void gui () {
|
||||||
@ -97,6 +98,7 @@ public class SkeletonRendererInspector : Editor {
|
|||||||
new GUIContent("Immutable Triangles", "Enable to optimize rendering for skeletons that never change attachment visbility"));
|
new GUIContent("Immutable Triangles", "Enable to optimize rendering for skeletons that never change attachment visbility"));
|
||||||
EditorGUILayout.PropertyField(normals);
|
EditorGUILayout.PropertyField(normals);
|
||||||
EditorGUILayout.PropertyField(tangents);
|
EditorGUILayout.PropertyField(tangents);
|
||||||
|
EditorGUILayout.PropertyField(front);
|
||||||
EditorGUILayout.PropertyField(submeshSeparators, true);
|
EditorGUILayout.PropertyField(submeshSeparators, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -38,7 +38,7 @@ using Spine;
|
|||||||
[ExecuteInEditMode, RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
|
[ExecuteInEditMode, RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
|
||||||
public class SkeletonRenderer : MonoBehaviour {
|
public class SkeletonRenderer : MonoBehaviour {
|
||||||
|
|
||||||
public delegate void SkeletonRendererDelegate (SkeletonRenderer skeletonRenderer);
|
public delegate void SkeletonRendererDelegate(SkeletonRenderer skeletonRenderer);
|
||||||
|
|
||||||
public SkeletonRendererDelegate OnReset;
|
public SkeletonRendererDelegate OnReset;
|
||||||
[System.NonSerialized]
|
[System.NonSerialized]
|
||||||
@ -50,6 +50,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
public bool calculateNormals, calculateTangents;
|
public bool calculateNormals, calculateTangents;
|
||||||
public float zSpacing;
|
public float zSpacing;
|
||||||
public bool renderMeshes = true, immutableTriangles;
|
public bool renderMeshes = true, immutableTriangles;
|
||||||
|
public bool frontFacing;
|
||||||
public bool logErrors = false;
|
public bool logErrors = false;
|
||||||
|
|
||||||
[SpineSlot]
|
[SpineSlot]
|
||||||
@ -70,9 +71,9 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
private Material[] sharedMaterials = new Material[0];
|
private Material[] sharedMaterials = new Material[0];
|
||||||
private readonly List<Material> submeshMaterials = new List<Material>();
|
private readonly List<Material> submeshMaterials = new List<Material>();
|
||||||
private readonly List<Submesh> submeshes = new List<Submesh>();
|
private readonly List<Submesh> submeshes = new List<Submesh>();
|
||||||
|
|
||||||
|
|
||||||
public virtual void Reset () {
|
|
||||||
|
public virtual void Reset() {
|
||||||
if (meshFilter != null)
|
if (meshFilter != null)
|
||||||
meshFilter.sharedMesh = null;
|
meshFilter.sharedMesh = null;
|
||||||
if (renderer != null)
|
if (renderer != null)
|
||||||
@ -99,12 +100,12 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
if (skeletonData == null)
|
if (skeletonData == null)
|
||||||
return;
|
return;
|
||||||
valid = true;
|
valid = true;
|
||||||
|
|
||||||
meshFilter = GetComponent<MeshFilter>();
|
meshFilter = GetComponent<MeshFilter>();
|
||||||
mesh1 = newMesh();
|
mesh1 = newMesh();
|
||||||
mesh2 = newMesh();
|
mesh2 = newMesh();
|
||||||
vertices = new Vector3[0];
|
vertices = new Vector3[0];
|
||||||
|
|
||||||
skeleton = new Skeleton(skeletonData);
|
skeleton = new Skeleton(skeletonData);
|
||||||
if (initialSkinName != null && initialSkinName.Length > 0 && initialSkinName != "default")
|
if (initialSkinName != null && initialSkinName.Length > 0 && initialSkinName != "default")
|
||||||
skeleton.SetSkin(initialSkinName);
|
skeleton.SetSkin(initialSkinName);
|
||||||
@ -114,33 +115,44 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
submeshSeparatorSlots.Add(skeleton.FindSlot(submeshSeparators[i]));
|
submeshSeparatorSlots.Add(skeleton.FindSlot(submeshSeparators[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Store flipped triangles for meshes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (OnReset != null)
|
if (OnReset != null)
|
||||||
OnReset(this);
|
OnReset(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnEnable() {
|
public virtual void OnEnable() {
|
||||||
if(mesh1 == null || mesh2 == null)
|
if (mesh1 == null || mesh2 == null)
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnDisable() {
|
public virtual void OnDisable() {
|
||||||
if (Application.isPlaying && gameObject.activeInHierarchy == false) {
|
if (Application.isPlaying && gameObject.activeInHierarchy == false) {
|
||||||
if (mesh1 != null)
|
if (mesh1 != null) {
|
||||||
Destroy(mesh1);
|
Destroy(mesh1);
|
||||||
if (mesh2 != null)
|
mesh1 = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mesh2 != null) {
|
||||||
Destroy(mesh2);
|
Destroy(mesh2);
|
||||||
|
mesh2 = null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Mesh newMesh () {
|
private Mesh newMesh() {
|
||||||
Mesh mesh = new Mesh();
|
Mesh mesh = new Mesh();
|
||||||
mesh.name = "Skeleton Mesh";
|
mesh.name = "Skeleton Mesh";
|
||||||
mesh.hideFlags = HideFlags.HideAndDontSave;
|
mesh.hideFlags = HideFlags.HideAndDontSave;
|
||||||
mesh.MarkDynamic();
|
mesh.MarkDynamic();
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void LateUpdate () {
|
public virtual void LateUpdate() {
|
||||||
if (!valid)
|
if (!valid)
|
||||||
return;
|
return;
|
||||||
// Count vertices and submesh triangles.
|
// Count vertices and submesh triangles.
|
||||||
@ -154,10 +166,10 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
for (int i = 0; i < drawOrderCount; i++) {
|
for (int i = 0; i < drawOrderCount; i++) {
|
||||||
Slot slot = drawOrder[i];
|
Slot slot = drawOrder[i];
|
||||||
Attachment attachment = slot.attachment;
|
Attachment attachment = slot.attachment;
|
||||||
|
|
||||||
object rendererObject;
|
object rendererObject;
|
||||||
int attachmentVertexCount, attachmentTriangleCount;
|
int attachmentVertexCount, attachmentTriangleCount;
|
||||||
|
|
||||||
if (attachment is RegionAttachment) {
|
if (attachment is RegionAttachment) {
|
||||||
rendererObject = ((RegionAttachment)attachment).RendererObject;
|
rendererObject = ((RegionAttachment)attachment).RendererObject;
|
||||||
attachmentVertexCount = 4;
|
attachmentVertexCount = 4;
|
||||||
@ -171,12 +183,12 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
attachmentVertexCount = meshAttachment.vertices.Length >> 1;
|
attachmentVertexCount = meshAttachment.vertices.Length >> 1;
|
||||||
attachmentTriangleCount = meshAttachment.triangles.Length;
|
attachmentTriangleCount = meshAttachment.triangles.Length;
|
||||||
} else if (attachment is SkinnedMeshAttachment) {
|
} else if (attachment is SkinnedMeshAttachment) {
|
||||||
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
||||||
rendererObject = meshAttachment.RendererObject;
|
rendererObject = meshAttachment.RendererObject;
|
||||||
attachmentVertexCount = meshAttachment.uvs.Length >> 1;
|
attachmentVertexCount = meshAttachment.uvs.Length >> 1;
|
||||||
attachmentTriangleCount = meshAttachment.triangles.Length;
|
attachmentTriangleCount = meshAttachment.triangles.Length;
|
||||||
} else
|
} else
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populate submesh when material changes.
|
// Populate submesh when material changes.
|
||||||
@ -189,19 +201,19 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
submeshStartSlotIndex = i;
|
submeshStartSlotIndex = i;
|
||||||
}
|
}
|
||||||
lastMaterial = material;
|
lastMaterial = material;
|
||||||
|
|
||||||
submeshTriangleCount += attachmentTriangleCount;
|
submeshTriangleCount += attachmentTriangleCount;
|
||||||
vertexCount += attachmentVertexCount;
|
vertexCount += attachmentVertexCount;
|
||||||
}
|
}
|
||||||
AddSubmesh(lastMaterial, submeshStartSlotIndex, drawOrderCount, submeshTriangleCount, submeshFirstVertex, true);
|
AddSubmesh(lastMaterial, submeshStartSlotIndex, drawOrderCount, submeshTriangleCount, submeshFirstVertex, true);
|
||||||
|
|
||||||
// Set materials.
|
// Set materials.
|
||||||
if (submeshMaterials.Count == sharedMaterials.Length)
|
if (submeshMaterials.Count == sharedMaterials.Length)
|
||||||
submeshMaterials.CopyTo(sharedMaterials);
|
submeshMaterials.CopyTo(sharedMaterials);
|
||||||
else
|
else
|
||||||
sharedMaterials = submeshMaterials.ToArray();
|
sharedMaterials = submeshMaterials.ToArray();
|
||||||
renderer.sharedMaterials = sharedMaterials;
|
renderer.sharedMaterials = sharedMaterials;
|
||||||
|
|
||||||
// Ensure mesh data is the right size.
|
// Ensure mesh data is the right size.
|
||||||
Vector3[] vertices = this.vertices;
|
Vector3[] vertices = this.vertices;
|
||||||
bool newTriangles = vertexCount > vertices.Length;
|
bool newTriangles = vertexCount > vertices.Length;
|
||||||
@ -219,7 +231,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
vertices[i] = zero;
|
vertices[i] = zero;
|
||||||
}
|
}
|
||||||
lastVertexCount = vertexCount;
|
lastVertexCount = vertexCount;
|
||||||
|
|
||||||
// Setup mesh.
|
// Setup mesh.
|
||||||
float[] tempVertices = this.tempVertices;
|
float[] tempVertices = this.tempVertices;
|
||||||
Vector2[] uvs = this.uvs;
|
Vector2[] uvs = this.uvs;
|
||||||
@ -234,13 +246,13 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
if (attachment is RegionAttachment) {
|
if (attachment is RegionAttachment) {
|
||||||
RegionAttachment regionAttachment = (RegionAttachment)attachment;
|
RegionAttachment regionAttachment = (RegionAttachment)attachment;
|
||||||
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] = new Vector3(tempVertices[RegionAttachment.X1], tempVertices[RegionAttachment.Y1], z);
|
||||||
vertices[vertexIndex + 1] = new Vector3(tempVertices[RegionAttachment.X4], tempVertices[RegionAttachment.Y4], z);
|
vertices[vertexIndex + 1] = new Vector3(tempVertices[RegionAttachment.X4], tempVertices[RegionAttachment.Y4], z);
|
||||||
vertices[vertexIndex + 2] = new Vector3(tempVertices[RegionAttachment.X2], tempVertices[RegionAttachment.Y2], z);
|
vertices[vertexIndex + 2] = new Vector3(tempVertices[RegionAttachment.X2], tempVertices[RegionAttachment.Y2], z);
|
||||||
vertices[vertexIndex + 3] = new Vector3(tempVertices[RegionAttachment.X3], tempVertices[RegionAttachment.Y3], z);
|
vertices[vertexIndex + 3] = new Vector3(tempVertices[RegionAttachment.X3], tempVertices[RegionAttachment.Y3], 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);
|
||||||
color.g = (byte)(g * slot.g * regionAttachment.g * color.a);
|
color.g = (byte)(g * slot.g * regionAttachment.g * color.a);
|
||||||
@ -251,13 +263,13 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
colors[vertexIndex + 1] = color;
|
colors[vertexIndex + 1] = color;
|
||||||
colors[vertexIndex + 2] = color;
|
colors[vertexIndex + 2] = color;
|
||||||
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] = new Vector2(regionUVs[RegionAttachment.X1], regionUVs[RegionAttachment.Y1]);
|
||||||
uvs[vertexIndex + 1] = new Vector2(regionUVs[RegionAttachment.X4], regionUVs[RegionAttachment.Y4]);
|
uvs[vertexIndex + 1] = new Vector2(regionUVs[RegionAttachment.X4], regionUVs[RegionAttachment.Y4]);
|
||||||
uvs[vertexIndex + 2] = new Vector2(regionUVs[RegionAttachment.X2], regionUVs[RegionAttachment.Y2]);
|
uvs[vertexIndex + 2] = new Vector2(regionUVs[RegionAttachment.X2], regionUVs[RegionAttachment.Y2]);
|
||||||
uvs[vertexIndex + 3] = new Vector2(regionUVs[RegionAttachment.X3], regionUVs[RegionAttachment.Y3]);
|
uvs[vertexIndex + 3] = new Vector2(regionUVs[RegionAttachment.X3], regionUVs[RegionAttachment.Y3]);
|
||||||
|
|
||||||
vertexIndex += 4;
|
vertexIndex += 4;
|
||||||
} else {
|
} else {
|
||||||
if (!renderMeshes)
|
if (!renderMeshes)
|
||||||
@ -268,14 +280,14 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
if (tempVertices.Length < meshVertexCount)
|
if (tempVertices.Length < meshVertexCount)
|
||||||
this.tempVertices = tempVertices = new float[meshVertexCount];
|
this.tempVertices = tempVertices = new float[meshVertexCount];
|
||||||
meshAttachment.ComputeWorldVertices(slot, tempVertices);
|
meshAttachment.ComputeWorldVertices(slot, tempVertices);
|
||||||
|
|
||||||
color.a = (byte)(a * slot.a * meshAttachment.a);
|
color.a = (byte)(a * slot.a * meshAttachment.a);
|
||||||
color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
|
color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
|
||||||
color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
|
color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
|
||||||
color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
|
color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
|
||||||
if (slot.data.additiveBlending)
|
if (slot.data.additiveBlending)
|
||||||
color.a = 0;
|
color.a = 0;
|
||||||
|
|
||||||
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++) {
|
||||||
@ -284,38 +296,38 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
|
uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
|
||||||
}
|
}
|
||||||
} else if (attachment is SkinnedMeshAttachment) {
|
} else if (attachment is SkinnedMeshAttachment) {
|
||||||
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
||||||
int meshVertexCount = meshAttachment.uvs.Length;
|
int meshVertexCount = meshAttachment.uvs.Length;
|
||||||
if (tempVertices.Length < meshVertexCount)
|
if (tempVertices.Length < meshVertexCount)
|
||||||
this.tempVertices = tempVertices = new float[meshVertexCount];
|
this.tempVertices = tempVertices = new float[meshVertexCount];
|
||||||
meshAttachment.ComputeWorldVertices(slot, tempVertices);
|
meshAttachment.ComputeWorldVertices(slot, tempVertices);
|
||||||
|
|
||||||
color.a = (byte)(a * slot.a * meshAttachment.a);
|
color.a = (byte)(a * slot.a * meshAttachment.a);
|
||||||
color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
|
color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
|
||||||
color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
|
color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
|
||||||
color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
|
color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
|
||||||
if (slot.data.additiveBlending)
|
if (slot.data.additiveBlending)
|
||||||
color.a = 0;
|
color.a = 0;
|
||||||
|
|
||||||
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] = new Vector3(tempVertices[ii], tempVertices[ii + 1], z);
|
||||||
colors[vertexIndex] = color;
|
colors[vertexIndex] = color;
|
||||||
uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
|
uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Double buffer mesh.
|
// Double buffer mesh.
|
||||||
Mesh mesh = useMesh1 ? mesh1 : mesh2;
|
Mesh mesh = useMesh1 ? mesh1 : mesh2;
|
||||||
meshFilter.sharedMesh = mesh;
|
meshFilter.sharedMesh = mesh;
|
||||||
|
|
||||||
mesh.vertices = vertices;
|
mesh.vertices = vertices;
|
||||||
mesh.colors32 = colors;
|
mesh.colors32 = colors;
|
||||||
mesh.uv = uvs;
|
mesh.uv = uvs;
|
||||||
|
|
||||||
int submeshCount = submeshMaterials.Count;
|
int submeshCount = submeshMaterials.Count;
|
||||||
mesh.subMeshCount = submeshCount;
|
mesh.subMeshCount = submeshCount;
|
||||||
for (int i = 0; i < submeshCount; ++i)
|
for (int i = 0; i < submeshCount; ++i)
|
||||||
@ -330,7 +342,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
(useMesh1 ? mesh2 : mesh1).vertices = vertices; // Set other mesh vertices.
|
(useMesh1 ? mesh2 : mesh1).vertices = vertices; // Set other mesh vertices.
|
||||||
mesh1.normals = normals;
|
mesh1.normals = normals;
|
||||||
mesh2.normals = normals;
|
mesh2.normals = normals;
|
||||||
|
|
||||||
if (calculateTangents) {
|
if (calculateTangents) {
|
||||||
Vector4[] tangents = new Vector4[vertexCount];
|
Vector4[] tangents = new Vector4[vertexCount];
|
||||||
Vector3 tangent = new Vector3(0, 0, 1);
|
Vector3 tangent = new Vector3(0, 0, 1);
|
||||||
@ -340,22 +352,22 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
mesh2.tangents = tangents;
|
mesh2.tangents = tangents;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
useMesh1 = !useMesh1;
|
useMesh1 = !useMesh1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Stores vertices and triangles for a single material. */
|
/** Stores vertices and triangles for a single material. */
|
||||||
private void AddSubmesh (Material material, int startSlot, int endSlot, int triangleCount, int firstVertex, bool lastSubmesh) {
|
private void AddSubmesh(Material material, int startSlot, int endSlot, int triangleCount, int firstVertex, bool lastSubmesh) {
|
||||||
int submeshIndex = submeshMaterials.Count;
|
int submeshIndex = submeshMaterials.Count;
|
||||||
submeshMaterials.Add(material);
|
submeshMaterials.Add(material);
|
||||||
|
|
||||||
if (submeshes.Count <= submeshIndex)
|
if (submeshes.Count <= submeshIndex)
|
||||||
submeshes.Add(new Submesh());
|
submeshes.Add(new Submesh());
|
||||||
else if (immutableTriangles)
|
else if (immutableTriangles)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Submesh submesh = submeshes[submeshIndex];
|
Submesh submesh = submeshes[submeshIndex];
|
||||||
|
|
||||||
int[] triangles = submesh.triangles;
|
int[] triangles = submesh.triangles;
|
||||||
int trianglesCapacity = triangles.Length;
|
int trianglesCapacity = triangles.Length;
|
||||||
if (lastSubmesh && trianglesCapacity > triangleCount) {
|
if (lastSubmesh && trianglesCapacity > triangleCount) {
|
||||||
@ -364,17 +376,18 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
triangles[i] = 0;
|
triangles[i] = 0;
|
||||||
submesh.triangleCount = triangleCount;
|
submesh.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];
|
submesh.triangles = triangles = new int[triangleCount];
|
||||||
submesh.triangleCount = 0;
|
submesh.triangleCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!renderMeshes) {
|
if (!renderMeshes && !frontFacing) {
|
||||||
// Use stored triangles if possible.
|
// Use stored triangles if possible.
|
||||||
if (submesh.firstVertex != firstVertex || submesh.triangleCount < triangleCount) {
|
if (submesh.firstVertex != firstVertex || submesh.triangleCount < triangleCount) {
|
||||||
submesh.triangleCount = triangleCount;
|
submesh.triangleCount = triangleCount;
|
||||||
submesh.firstVertex = firstVertex;
|
submesh.firstVertex = firstVertex;
|
||||||
for (int i = 0; i < triangleCount; i += 6, firstVertex += 4) {
|
int drawOrderIndex = 0;
|
||||||
|
for (int i = 0; i < triangleCount; i += 6, firstVertex += 4, drawOrderIndex++) {
|
||||||
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;
|
||||||
@ -389,14 +402,27 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
// Store triangles.
|
// Store triangles.
|
||||||
List<Slot> drawOrder = skeleton.DrawOrder;
|
List<Slot> drawOrder = skeleton.DrawOrder;
|
||||||
for (int i = startSlot, triangleIndex = 0; i < endSlot; i++) {
|
for (int i = startSlot, triangleIndex = 0; i < endSlot; i++) {
|
||||||
Attachment attachment = drawOrder[i].attachment;
|
Slot slot = drawOrder[i];
|
||||||
|
Attachment attachment = slot.attachment;
|
||||||
|
bool flip = frontFacing && ((slot.Bone.WorldFlipX != slot.Bone.WorldFlipY) != (Mathf.Sign(slot.Bone.WorldScaleX) != Mathf.Sign(slot.bone.WorldScaleY)));
|
||||||
|
|
||||||
if (attachment is RegionAttachment) {
|
if (attachment is RegionAttachment) {
|
||||||
triangles[triangleIndex] = firstVertex;
|
if (!flip) {
|
||||||
triangles[triangleIndex + 1] = firstVertex + 2;
|
triangles[triangleIndex] = firstVertex;
|
||||||
triangles[triangleIndex + 2] = firstVertex + 1;
|
triangles[triangleIndex + 1] = firstVertex + 2;
|
||||||
triangles[triangleIndex + 3] = firstVertex + 2;
|
triangles[triangleIndex + 2] = firstVertex + 1;
|
||||||
triangles[triangleIndex + 4] = firstVertex + 3;
|
triangles[triangleIndex + 3] = firstVertex + 2;
|
||||||
triangles[triangleIndex + 5] = firstVertex + 1;
|
triangles[triangleIndex + 4] = firstVertex + 3;
|
||||||
|
triangles[triangleIndex + 5] = firstVertex + 1;
|
||||||
|
} else {
|
||||||
|
triangles[triangleIndex] = firstVertex + 1;
|
||||||
|
triangles[triangleIndex + 1] = firstVertex + 2;
|
||||||
|
triangles[triangleIndex + 2] = firstVertex;
|
||||||
|
triangles[triangleIndex + 3] = firstVertex + 1;
|
||||||
|
triangles[triangleIndex + 4] = firstVertex + 3;
|
||||||
|
triangles[triangleIndex + 5] = firstVertex + 2;
|
||||||
|
}
|
||||||
|
|
||||||
triangleIndex += 6;
|
triangleIndex += 6;
|
||||||
firstVertex += 4;
|
firstVertex += 4;
|
||||||
continue;
|
continue;
|
||||||
@ -408,17 +434,28 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
attachmentVertexCount = meshAttachment.vertices.Length >> 1;
|
attachmentVertexCount = meshAttachment.vertices.Length >> 1;
|
||||||
attachmentTriangles = meshAttachment.triangles;
|
attachmentTriangles = meshAttachment.triangles;
|
||||||
} else if (attachment is SkinnedMeshAttachment) {
|
} else if (attachment is SkinnedMeshAttachment) {
|
||||||
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
||||||
attachmentVertexCount = meshAttachment.uvs.Length >> 1;
|
attachmentVertexCount = meshAttachment.uvs.Length >> 1;
|
||||||
attachmentTriangles = meshAttachment.triangles;
|
attachmentTriangles = meshAttachment.triangles;
|
||||||
} else
|
} else
|
||||||
continue;
|
continue;
|
||||||
for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii++, triangleIndex++)
|
|
||||||
triangles[triangleIndex] = firstVertex + attachmentTriangles[ii];
|
if (flip) {
|
||||||
|
for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii += 3, triangleIndex += 3) {
|
||||||
|
triangles[triangleIndex + 2] = firstVertex + attachmentTriangles[ii];
|
||||||
|
triangles[triangleIndex + 1] = firstVertex + attachmentTriangles[ii + 1];
|
||||||
|
triangles[triangleIndex] = firstVertex + attachmentTriangles[ii + 2];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii++, triangleIndex++) {
|
||||||
|
triangles[triangleIndex] = firstVertex + attachmentTriangles[ii];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
firstVertex += attachmentVertexCount;
|
firstVertex += attachmentVertexCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
void OnDrawGizmos() {
|
void OnDrawGizmos() {
|
||||||
// Make selection easier by drawing a clear gizmo over the skeleton.
|
// Make selection easier by drawing a clear gizmo over the skeleton.
|
||||||
@ -434,7 +471,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
float width = max.x - min.x;
|
float width = max.x - min.x;
|
||||||
float height = max.y - min.y;
|
float height = max.y - min.y;
|
||||||
gizmosCenter = new Vector3(min.x + (width / 2f), min.y + (height / 2f), 0f);
|
gizmosCenter = new Vector3(min.x + (width / 2f), min.y + (height / 2f), 0f);
|
||||||
gizmosSize = new Vector3(width, height, 1f);
|
gizmosSize = new Vector3(width, height, 1f);
|
||||||
Gizmos.color = Color.clear;
|
Gizmos.color = Color.clear;
|
||||||
Gizmos.matrix = transform.localToWorldMatrix;
|
Gizmos.matrix = transform.localToWorldMatrix;
|
||||||
Gizmos.DrawCube(gizmosCenter, gizmosSize);
|
Gizmos.DrawCube(gizmosCenter, gizmosSize);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user