mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-20 17:26:01 +08:00
Optimization to not render meshes. Better inspectors.
This commit is contained in:
parent
b316b8d3e1
commit
6983ec6fd3
@ -33,27 +33,24 @@ using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[CustomEditor(typeof(SkeletonAnimation))]
|
||||
public class SkeletonAnimationInspector : Editor {
|
||||
private SerializedProperty skeletonDataAsset, initialSkinName, timeScale, normals, tangents;
|
||||
private SerializedProperty animationName, loop;
|
||||
public class SkeletonAnimationInspector : SkeletonRendererInspector {
|
||||
protected SerializedProperty animationName, loop, timeScale;
|
||||
|
||||
void OnEnable () {
|
||||
skeletonDataAsset = serializedObject.FindProperty("skeletonDataAsset");
|
||||
protected override void OnEnable () {
|
||||
base.OnEnable();
|
||||
animationName = serializedObject.FindProperty("_animationName");
|
||||
loop = serializedObject.FindProperty("loop");
|
||||
initialSkinName = serializedObject.FindProperty("initialSkinName");
|
||||
timeScale = serializedObject.FindProperty("timeScale");
|
||||
normals = serializedObject.FindProperty("calculateNormals");
|
||||
tangents = serializedObject.FindProperty("calculateTangents");
|
||||
}
|
||||
|
||||
override public void OnInspectorGUI () {
|
||||
serializedObject.Update();
|
||||
protected override void gui () {
|
||||
base.gui();
|
||||
|
||||
SkeletonAnimation component = (SkeletonAnimation)target;
|
||||
|
||||
EditorGUILayout.PropertyField(skeletonDataAsset);
|
||||
|
||||
if (component.skeleton != null) {
|
||||
if (component.valid) {
|
||||
// Initial skin name.
|
||||
String[] skins = new String[component.skeleton.Data.Skins.Count];
|
||||
int skinIndex = 0;
|
||||
@ -98,17 +95,5 @@ public class SkeletonAnimationInspector : Editor {
|
||||
EditorGUILayout.LabelField("Loop");
|
||||
loop.boolValue = EditorGUILayout.Toggle(loop.boolValue);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.PropertyField(timeScale);
|
||||
EditorGUILayout.PropertyField(normals);
|
||||
EditorGUILayout.PropertyField(tangents);
|
||||
|
||||
if (serializedObject.ApplyModifiedProperties() ||
|
||||
(Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed")
|
||||
) {
|
||||
if (!Application.isPlaying) {
|
||||
component.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,23 +34,22 @@ using UnityEngine;
|
||||
|
||||
[CustomEditor(typeof(SkeletonRenderer))]
|
||||
public class SkeletonRendererInspector : Editor {
|
||||
private SerializedProperty skeletonDataAsset, initialSkinName, timeScale, normals, tangents;
|
||||
protected SerializedProperty skeletonDataAsset, initialSkinName, normals, tangents, meshes;
|
||||
|
||||
void OnEnable () {
|
||||
protected virtual void OnEnable () {
|
||||
skeletonDataAsset = serializedObject.FindProperty("skeletonDataAsset");
|
||||
initialSkinName = serializedObject.FindProperty("initialSkinName");
|
||||
timeScale = serializedObject.FindProperty("timeScale");
|
||||
normals = serializedObject.FindProperty("calculateNormals");
|
||||
tangents = serializedObject.FindProperty("calculateTangents");
|
||||
meshes = serializedObject.FindProperty("renderMeshes");
|
||||
}
|
||||
|
||||
override public void OnInspectorGUI () {
|
||||
serializedObject.Update();
|
||||
protected virtual void gui () {
|
||||
SkeletonRenderer component = (SkeletonRenderer)target;
|
||||
|
||||
EditorGUILayout.PropertyField(skeletonDataAsset);
|
||||
|
||||
if (component.skeleton != null) {
|
||||
if (component.valid) {
|
||||
// Initial skin name.
|
||||
String[] skins = new String[component.skeleton.Data.Skins.Count];
|
||||
int skinIndex = 0;
|
||||
@ -60,26 +59,28 @@ public class SkeletonRendererInspector : Editor {
|
||||
if (name == initialSkinName.stringValue)
|
||||
skinIndex = i;
|
||||
}
|
||||
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Initial Skin");
|
||||
EditorGUIUtility.LookLikeControls();
|
||||
skinIndex = EditorGUILayout.Popup(skinIndex, skins);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
|
||||
initialSkinName.stringValue = skins[skinIndex];
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(timeScale);
|
||||
|
||||
EditorGUILayout.PropertyField(meshes);
|
||||
EditorGUILayout.PropertyField(normals);
|
||||
EditorGUILayout.PropertyField(tangents);
|
||||
|
||||
}
|
||||
|
||||
override public void OnInspectorGUI () {
|
||||
serializedObject.Update();
|
||||
gui();
|
||||
if (serializedObject.ApplyModifiedProperties() ||
|
||||
(Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed")
|
||||
) {
|
||||
if (!Application.isPlaying) {
|
||||
component.Reset();
|
||||
}
|
||||
if (!Application.isPlaying) ((SkeletonRenderer)target).Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,6 +47,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
public bool calculateNormals;
|
||||
public bool calculateTangents;
|
||||
public float zSpacing;
|
||||
public bool renderMeshes;
|
||||
|
||||
private MeshFilter meshFilter;
|
||||
private Mesh mesh, mesh1, mesh2;
|
||||
@ -108,9 +109,9 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
return mesh;
|
||||
}
|
||||
|
||||
public virtual void OnWillRenderObject () {
|
||||
public virtual void LateUpdate () {
|
||||
if (!valid) return;
|
||||
|
||||
|
||||
// Count vertices and submesh triangles.
|
||||
int vertexCount = 0;
|
||||
int submeshTriangleCount = 0, submeshFirstVertex = 0, submeshStartSlotIndex = 0;
|
||||
@ -118,6 +119,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
submeshMaterials.Clear();
|
||||
List<Slot> drawOrder = skeleton.DrawOrder;
|
||||
int drawOrderCount = drawOrder.Count;
|
||||
bool renderMeshes = this.renderMeshes;
|
||||
for (int i = 0; i < drawOrderCount; i++) {
|
||||
Attachment attachment = drawOrder[i].attachment;
|
||||
|
||||
@ -128,23 +130,26 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
rendererObject = ((RegionAttachment)attachment).RendererObject;
|
||||
attachmentVertexCount = 4;
|
||||
attachmentTriangleCount = 6;
|
||||
} else if (attachment is MeshAttachment) {
|
||||
MeshAttachment meshAttachment = (MeshAttachment)attachment;
|
||||
rendererObject = meshAttachment.RendererObject;
|
||||
attachmentVertexCount = meshAttachment.vertices.Length / 2;
|
||||
attachmentTriangleCount = meshAttachment.triangles.Length;
|
||||
} else if (attachment is SkinnedMeshAttachment) {
|
||||
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
||||
rendererObject = meshAttachment.RendererObject;
|
||||
attachmentVertexCount = meshAttachment.uvs.Length / 2;
|
||||
attachmentTriangleCount = meshAttachment.triangles.Length;
|
||||
} else
|
||||
continue;
|
||||
} else {
|
||||
if (!renderMeshes) continue;
|
||||
if (attachment is MeshAttachment) {
|
||||
MeshAttachment meshAttachment = (MeshAttachment)attachment;
|
||||
rendererObject = meshAttachment.RendererObject;
|
||||
attachmentVertexCount = meshAttachment.vertices.Length >> 1;
|
||||
attachmentTriangleCount = meshAttachment.triangles.Length;
|
||||
} else if (attachment is SkinnedMeshAttachment) {
|
||||
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
||||
rendererObject = meshAttachment.RendererObject;
|
||||
attachmentVertexCount = meshAttachment.uvs.Length >> 1;
|
||||
attachmentTriangleCount = meshAttachment.triangles.Length;
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
|
||||
// Populate submesh when material changes.
|
||||
Material material = (Material)rendererObject;
|
||||
if (lastMaterial != material && lastMaterial != null) {
|
||||
addSubmesh(lastMaterial, submeshStartSlotIndex, i, submeshTriangleCount, submeshFirstVertex, false);
|
||||
AddSubmesh(lastMaterial, submeshStartSlotIndex, i, submeshTriangleCount, submeshFirstVertex, false);
|
||||
submeshTriangleCount = 0;
|
||||
submeshFirstVertex = vertexCount;
|
||||
submeshStartSlotIndex = i;
|
||||
@ -154,7 +159,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
submeshTriangleCount += attachmentTriangleCount;
|
||||
vertexCount += attachmentVertexCount;
|
||||
}
|
||||
addSubmesh(lastMaterial, submeshStartSlotIndex, drawOrderCount, submeshTriangleCount, submeshFirstVertex, true);
|
||||
AddSubmesh(lastMaterial, submeshStartSlotIndex, drawOrderCount, submeshTriangleCount, submeshFirstVertex, true);
|
||||
|
||||
// Set materials.
|
||||
if (submeshMaterials.Count == sharedMaterials.Length)
|
||||
@ -219,43 +224,46 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
uvs[vertexIndex + 3] = new Vector2(regionUVs[RegionAttachment.X3], regionUVs[RegionAttachment.Y3]);
|
||||
|
||||
vertexIndex += 4;
|
||||
} else if (attachment is MeshAttachment) {
|
||||
MeshAttachment meshAttachment = (MeshAttachment)attachment;
|
||||
int meshVertexCount = meshAttachment.vertices.Length;
|
||||
if (tempVertices.Length < meshVertexCount) tempVertices = new float[meshVertexCount];
|
||||
meshAttachment.ComputeWorldVertices(x, y, slot, tempVertices);
|
||||
|
||||
color.a = (byte)(a * slot.a * meshAttachment.a);
|
||||
color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
|
||||
color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
|
||||
color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
|
||||
if (slot.data.additiveBlending) color.a = 0;
|
||||
|
||||
float[] meshUVs = meshAttachment.uvs;
|
||||
float z = i * zSpacing;
|
||||
for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++) {
|
||||
vertices[vertexIndex] = new Vector3(tempVertices[ii], tempVertices[ii + 1], z);
|
||||
colors[vertexIndex] = color;
|
||||
uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
|
||||
}
|
||||
} else if (attachment is SkinnedMeshAttachment) {
|
||||
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
||||
int meshVertexCount = meshAttachment.uvs.Length;
|
||||
if (tempVertices.Length < meshVertexCount) tempVertices = new float[meshVertexCount];
|
||||
meshAttachment.ComputeWorldVertices(x, y, slot, tempVertices);
|
||||
|
||||
color.a = (byte)(a * slot.a * meshAttachment.a);
|
||||
color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
|
||||
color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
|
||||
color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
|
||||
if (slot.data.additiveBlending) color.a = 0;
|
||||
|
||||
float[] meshUVs = meshAttachment.uvs;
|
||||
float z = i * zSpacing;
|
||||
for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++) {
|
||||
vertices[vertexIndex] = new Vector3(tempVertices[ii], tempVertices[ii + 1], z);
|
||||
colors[vertexIndex] = color;
|
||||
uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
|
||||
} else {
|
||||
if (!renderMeshes) continue;
|
||||
if (attachment is MeshAttachment) {
|
||||
MeshAttachment meshAttachment = (MeshAttachment)attachment;
|
||||
int meshVertexCount = meshAttachment.vertices.Length;
|
||||
if (tempVertices.Length < meshVertexCount) tempVertices = new float[meshVertexCount];
|
||||
meshAttachment.ComputeWorldVertices(x, y, slot, tempVertices);
|
||||
|
||||
color.a = (byte)(a * slot.a * meshAttachment.a);
|
||||
color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
|
||||
color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
|
||||
color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
|
||||
if (slot.data.additiveBlending) color.a = 0;
|
||||
|
||||
float[] meshUVs = meshAttachment.uvs;
|
||||
float z = i * zSpacing;
|
||||
for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++) {
|
||||
vertices[vertexIndex] = new Vector3(tempVertices[ii], tempVertices[ii + 1], z);
|
||||
colors[vertexIndex] = color;
|
||||
uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
|
||||
}
|
||||
} else if (attachment is SkinnedMeshAttachment) {
|
||||
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
||||
int meshVertexCount = meshAttachment.uvs.Length;
|
||||
if (tempVertices.Length < meshVertexCount) tempVertices = new float[meshVertexCount];
|
||||
meshAttachment.ComputeWorldVertices(x, y, slot, tempVertices);
|
||||
|
||||
color.a = (byte)(a * slot.a * meshAttachment.a);
|
||||
color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
|
||||
color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
|
||||
color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
|
||||
if (slot.data.additiveBlending) color.a = 0;
|
||||
|
||||
float[] meshUVs = meshAttachment.uvs;
|
||||
float z = i * zSpacing;
|
||||
for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++) {
|
||||
vertices[vertexIndex] = new Vector3(tempVertices[ii], tempVertices[ii + 1], z);
|
||||
colors[vertexIndex] = color;
|
||||
uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -297,7 +305,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
}
|
||||
|
||||
/** 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;
|
||||
submeshMaterials.Add(material);
|
||||
|
||||
@ -317,6 +325,24 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
submesh.triangleCount = 0;
|
||||
}
|
||||
|
||||
if (!renderMeshes) {
|
||||
// Use stored triangles if possible.
|
||||
if (submesh.firstVertex != firstVertex || submesh.triangleCount < triangleCount) {
|
||||
submesh.triangleCount = triangleCount;
|
||||
submesh.firstVertex = firstVertex;
|
||||
for (int i = 0; i < triangleCount; i += 6, firstVertex += 4) {
|
||||
triangles[i] = firstVertex;
|
||||
triangles[i + 1] = firstVertex + 2;
|
||||
triangles[i + 2] = firstVertex + 1;
|
||||
triangles[i + 3] = firstVertex + 2;
|
||||
triangles[i + 4] = firstVertex + 3;
|
||||
triangles[i + 5] = firstVertex + 1;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Store triangles.
|
||||
List<Slot> drawOrder = skeleton.DrawOrder;
|
||||
for (int i = startSlot, triangleIndex = 0; i < endSlot; i++) {
|
||||
Attachment attachment = drawOrder[i].attachment;
|
||||
@ -327,11 +353,11 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
attachmentTriangles = quadTriangles;
|
||||
} else if (attachment is MeshAttachment) {
|
||||
MeshAttachment meshAttachment = (MeshAttachment)attachment;
|
||||
attachmentVertexCount = meshAttachment.vertices.Length / 2;
|
||||
attachmentVertexCount = meshAttachment.vertices.Length >> 1;
|
||||
attachmentTriangles = meshAttachment.triangles;
|
||||
} else if (attachment is SkinnedMeshAttachment) {
|
||||
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
||||
attachmentVertexCount = meshAttachment.uvs.Length / 2;
|
||||
attachmentVertexCount = meshAttachment.uvs.Length >> 1;
|
||||
attachmentTriangles = meshAttachment.triangles;
|
||||
} else
|
||||
continue;
|
||||
@ -367,4 +393,5 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
class Submesh {
|
||||
public int[] triangles = new int[0];
|
||||
public int triangleCount;
|
||||
public int firstVertex = -1;
|
||||
}
|
||||
|
||||
Binary file not shown.
@ -33,27 +33,24 @@ using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[CustomEditor(typeof(SkeletonAnimation))]
|
||||
public class SkeletonAnimationInspector : Editor {
|
||||
private SerializedProperty skeletonDataAsset, initialSkinName, timeScale, normals, tangents;
|
||||
private SerializedProperty animationName, loop;
|
||||
public class SkeletonAnimationInspector : SkeletonRendererInspector {
|
||||
protected SerializedProperty animationName, loop, timeScale;
|
||||
|
||||
void OnEnable () {
|
||||
skeletonDataAsset = serializedObject.FindProperty("skeletonDataAsset");
|
||||
protected override void OnEnable () {
|
||||
base.OnEnable();
|
||||
animationName = serializedObject.FindProperty("_animationName");
|
||||
loop = serializedObject.FindProperty("loop");
|
||||
initialSkinName = serializedObject.FindProperty("initialSkinName");
|
||||
timeScale = serializedObject.FindProperty("timeScale");
|
||||
normals = serializedObject.FindProperty("calculateNormals");
|
||||
tangents = serializedObject.FindProperty("calculateTangents");
|
||||
}
|
||||
|
||||
override public void OnInspectorGUI () {
|
||||
serializedObject.Update();
|
||||
protected override void gui () {
|
||||
base.gui();
|
||||
|
||||
SkeletonAnimation component = (SkeletonAnimation)target;
|
||||
|
||||
EditorGUILayout.PropertyField(skeletonDataAsset);
|
||||
|
||||
if (component.skeleton != null) {
|
||||
if (component.valid) {
|
||||
// Initial skin name.
|
||||
String[] skins = new String[component.skeleton.Data.Skins.Count];
|
||||
int skinIndex = 0;
|
||||
@ -98,17 +95,5 @@ public class SkeletonAnimationInspector : Editor {
|
||||
EditorGUILayout.LabelField("Loop");
|
||||
loop.boolValue = EditorGUILayout.Toggle(loop.boolValue);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.PropertyField(timeScale);
|
||||
EditorGUILayout.PropertyField(normals);
|
||||
EditorGUILayout.PropertyField(tangents);
|
||||
|
||||
if (serializedObject.ApplyModifiedProperties() ||
|
||||
(Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed")
|
||||
) {
|
||||
if (!Application.isPlaying) {
|
||||
component.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,23 +34,22 @@ using UnityEngine;
|
||||
|
||||
[CustomEditor(typeof(SkeletonRenderer))]
|
||||
public class SkeletonRendererInspector : Editor {
|
||||
private SerializedProperty skeletonDataAsset, initialSkinName, timeScale, normals, tangents;
|
||||
protected SerializedProperty skeletonDataAsset, initialSkinName, normals, tangents, meshes;
|
||||
|
||||
void OnEnable () {
|
||||
protected virtual void OnEnable () {
|
||||
skeletonDataAsset = serializedObject.FindProperty("skeletonDataAsset");
|
||||
initialSkinName = serializedObject.FindProperty("initialSkinName");
|
||||
timeScale = serializedObject.FindProperty("timeScale");
|
||||
normals = serializedObject.FindProperty("calculateNormals");
|
||||
tangents = serializedObject.FindProperty("calculateTangents");
|
||||
meshes = serializedObject.FindProperty("renderMeshes");
|
||||
}
|
||||
|
||||
override public void OnInspectorGUI () {
|
||||
serializedObject.Update();
|
||||
protected virtual void gui () {
|
||||
SkeletonRenderer component = (SkeletonRenderer)target;
|
||||
|
||||
EditorGUILayout.PropertyField(skeletonDataAsset);
|
||||
|
||||
if (component.skeleton != null) {
|
||||
if (component.valid) {
|
||||
// Initial skin name.
|
||||
String[] skins = new String[component.skeleton.Data.Skins.Count];
|
||||
int skinIndex = 0;
|
||||
@ -60,26 +59,28 @@ public class SkeletonRendererInspector : Editor {
|
||||
if (name == initialSkinName.stringValue)
|
||||
skinIndex = i;
|
||||
}
|
||||
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Initial Skin");
|
||||
EditorGUIUtility.LookLikeControls();
|
||||
skinIndex = EditorGUILayout.Popup(skinIndex, skins);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
|
||||
initialSkinName.stringValue = skins[skinIndex];
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(timeScale);
|
||||
|
||||
EditorGUILayout.PropertyField(meshes);
|
||||
EditorGUILayout.PropertyField(normals);
|
||||
EditorGUILayout.PropertyField(tangents);
|
||||
|
||||
}
|
||||
|
||||
override public void OnInspectorGUI () {
|
||||
serializedObject.Update();
|
||||
gui();
|
||||
if (serializedObject.ApplyModifiedProperties() ||
|
||||
(Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed")
|
||||
) {
|
||||
if (!Application.isPlaying) {
|
||||
component.Reset();
|
||||
}
|
||||
if (!Application.isPlaying) ((SkeletonRenderer)target).Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,12 +41,13 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
public bool valid;
|
||||
[System.NonSerialized]
|
||||
public Skeleton skeleton;
|
||||
|
||||
|
||||
public SkeletonDataAsset skeletonDataAsset;
|
||||
public String initialSkinName;
|
||||
public bool calculateNormals;
|
||||
public bool calculateTangents;
|
||||
public float zSpacing;
|
||||
public bool renderMeshes;
|
||||
|
||||
private MeshFilter meshFilter;
|
||||
private Mesh mesh, mesh1, mesh2;
|
||||
@ -76,7 +77,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
submeshMaterials.Clear();
|
||||
submeshes.Clear();
|
||||
skeleton = null;
|
||||
|
||||
|
||||
valid = false;
|
||||
if (!skeletonDataAsset) {
|
||||
Debug.LogError("Missing SkeletonData asset.", this);
|
||||
@ -84,7 +85,8 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
}
|
||||
SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(false);
|
||||
if (skeletonData == null) return;
|
||||
|
||||
valid = true;
|
||||
|
||||
meshFilter = GetComponent<MeshFilter>();
|
||||
mesh1 = newMesh();
|
||||
mesh2 = newMesh();
|
||||
@ -107,7 +109,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
return mesh;
|
||||
}
|
||||
|
||||
public virtual void OnWillRenderObject () {
|
||||
public virtual void LateUpdate () {
|
||||
if (!valid) return;
|
||||
|
||||
// Count vertices and submesh triangles.
|
||||
@ -117,6 +119,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
submeshMaterials.Clear();
|
||||
List<Slot> drawOrder = skeleton.DrawOrder;
|
||||
int drawOrderCount = drawOrder.Count;
|
||||
bool renderMeshes = this.renderMeshes;
|
||||
for (int i = 0; i < drawOrderCount; i++) {
|
||||
Attachment attachment = drawOrder[i].attachment;
|
||||
|
||||
@ -127,23 +130,26 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
rendererObject = ((RegionAttachment)attachment).RendererObject;
|
||||
attachmentVertexCount = 4;
|
||||
attachmentTriangleCount = 6;
|
||||
} else if (attachment is MeshAttachment) {
|
||||
MeshAttachment meshAttachment = (MeshAttachment)attachment;
|
||||
rendererObject = meshAttachment.RendererObject;
|
||||
attachmentVertexCount = meshAttachment.vertices.Length / 2;
|
||||
attachmentTriangleCount = meshAttachment.triangles.Length;
|
||||
} else if (attachment is SkinnedMeshAttachment) {
|
||||
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
||||
rendererObject = meshAttachment.RendererObject;
|
||||
attachmentVertexCount = meshAttachment.uvs.Length / 2;
|
||||
attachmentTriangleCount = meshAttachment.triangles.Length;
|
||||
} else
|
||||
continue;
|
||||
} else {
|
||||
if (!renderMeshes) continue;
|
||||
if (attachment is MeshAttachment) {
|
||||
MeshAttachment meshAttachment = (MeshAttachment)attachment;
|
||||
rendererObject = meshAttachment.RendererObject;
|
||||
attachmentVertexCount = meshAttachment.vertices.Length >> 1;
|
||||
attachmentTriangleCount = meshAttachment.triangles.Length;
|
||||
} else if (attachment is SkinnedMeshAttachment) {
|
||||
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
||||
rendererObject = meshAttachment.RendererObject;
|
||||
attachmentVertexCount = meshAttachment.uvs.Length >> 1;
|
||||
attachmentTriangleCount = meshAttachment.triangles.Length;
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
|
||||
// Populate submesh when material changes.
|
||||
Material material = (Material)((AtlasRegion)rendererObject).page.rendererObject;
|
||||
if (lastMaterial != material && lastMaterial != null) {
|
||||
addSubmesh(lastMaterial, submeshStartSlotIndex, i, submeshTriangleCount, submeshFirstVertex, false);
|
||||
AddSubmesh(lastMaterial, submeshStartSlotIndex, i, submeshTriangleCount, submeshFirstVertex, false);
|
||||
submeshTriangleCount = 0;
|
||||
submeshFirstVertex = vertexCount;
|
||||
submeshStartSlotIndex = i;
|
||||
@ -153,7 +159,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
submeshTriangleCount += attachmentTriangleCount;
|
||||
vertexCount += attachmentVertexCount;
|
||||
}
|
||||
addSubmesh(lastMaterial, submeshStartSlotIndex, drawOrderCount, submeshTriangleCount, submeshFirstVertex, true);
|
||||
AddSubmesh(lastMaterial, submeshStartSlotIndex, drawOrderCount, submeshTriangleCount, submeshFirstVertex, true);
|
||||
|
||||
// Set materials.
|
||||
if (submeshMaterials.Count == sharedMaterials.Length)
|
||||
@ -218,43 +224,46 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
uvs[vertexIndex + 3] = new Vector2(regionUVs[RegionAttachment.X3], regionUVs[RegionAttachment.Y3]);
|
||||
|
||||
vertexIndex += 4;
|
||||
} else if (attachment is MeshAttachment) {
|
||||
MeshAttachment meshAttachment = (MeshAttachment)attachment;
|
||||
int meshVertexCount = meshAttachment.vertices.Length;
|
||||
if (tempVertices.Length < meshVertexCount) tempVertices = new float[meshVertexCount];
|
||||
meshAttachment.ComputeWorldVertices(x, y, slot, tempVertices);
|
||||
|
||||
color.a = (byte)(a * slot.a * meshAttachment.a);
|
||||
color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
|
||||
color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
|
||||
color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
|
||||
if (slot.data.additiveBlending) color.a = 0;
|
||||
|
||||
float[] meshUVs = meshAttachment.uvs;
|
||||
float z = i * zSpacing;
|
||||
for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++) {
|
||||
vertices[vertexIndex] = new Vector3(tempVertices[ii], tempVertices[ii + 1], z);
|
||||
colors[vertexIndex] = color;
|
||||
uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
|
||||
}
|
||||
} else if (attachment is SkinnedMeshAttachment) {
|
||||
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
||||
int meshVertexCount = meshAttachment.uvs.Length;
|
||||
if (tempVertices.Length < meshVertexCount) tempVertices = new float[meshVertexCount];
|
||||
meshAttachment.ComputeWorldVertices(x, y, slot, tempVertices);
|
||||
|
||||
color.a = (byte)(a * slot.a * meshAttachment.a);
|
||||
color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
|
||||
color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
|
||||
color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
|
||||
if (slot.data.additiveBlending) color.a = 0;
|
||||
|
||||
float[] meshUVs = meshAttachment.uvs;
|
||||
float z = i * zSpacing;
|
||||
for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++) {
|
||||
vertices[vertexIndex] = new Vector3(tempVertices[ii], tempVertices[ii + 1], z);
|
||||
colors[vertexIndex] = color;
|
||||
uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
|
||||
} else {
|
||||
if (!renderMeshes) continue;
|
||||
if (attachment is MeshAttachment) {
|
||||
MeshAttachment meshAttachment = (MeshAttachment)attachment;
|
||||
int meshVertexCount = meshAttachment.vertices.Length;
|
||||
if (tempVertices.Length < meshVertexCount) tempVertices = new float[meshVertexCount];
|
||||
meshAttachment.ComputeWorldVertices(x, y, slot, tempVertices);
|
||||
|
||||
color.a = (byte)(a * slot.a * meshAttachment.a);
|
||||
color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
|
||||
color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
|
||||
color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
|
||||
if (slot.data.additiveBlending) color.a = 0;
|
||||
|
||||
float[] meshUVs = meshAttachment.uvs;
|
||||
float z = i * zSpacing;
|
||||
for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++) {
|
||||
vertices[vertexIndex] = new Vector3(tempVertices[ii], tempVertices[ii + 1], z);
|
||||
colors[vertexIndex] = color;
|
||||
uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
|
||||
}
|
||||
} else if (attachment is SkinnedMeshAttachment) {
|
||||
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
||||
int meshVertexCount = meshAttachment.uvs.Length;
|
||||
if (tempVertices.Length < meshVertexCount) tempVertices = new float[meshVertexCount];
|
||||
meshAttachment.ComputeWorldVertices(x, y, slot, tempVertices);
|
||||
|
||||
color.a = (byte)(a * slot.a * meshAttachment.a);
|
||||
color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
|
||||
color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
|
||||
color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
|
||||
if (slot.data.additiveBlending) color.a = 0;
|
||||
|
||||
float[] meshUVs = meshAttachment.uvs;
|
||||
float z = i * zSpacing;
|
||||
for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++) {
|
||||
vertices[vertexIndex] = new Vector3(tempVertices[ii], tempVertices[ii + 1], z);
|
||||
colors[vertexIndex] = color;
|
||||
uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -296,7 +305,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
}
|
||||
|
||||
/** 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;
|
||||
submeshMaterials.Add(material);
|
||||
|
||||
@ -316,6 +325,24 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
submesh.triangleCount = 0;
|
||||
}
|
||||
|
||||
if (!renderMeshes) {
|
||||
// Use stored triangles if possible.
|
||||
if (submesh.firstVertex != firstVertex || submesh.triangleCount < triangleCount) {
|
||||
submesh.triangleCount = triangleCount;
|
||||
submesh.firstVertex = firstVertex;
|
||||
for (int i = 0; i < triangleCount; i += 6, firstVertex += 4) {
|
||||
triangles[i] = firstVertex;
|
||||
triangles[i + 1] = firstVertex + 2;
|
||||
triangles[i + 2] = firstVertex + 1;
|
||||
triangles[i + 3] = firstVertex + 2;
|
||||
triangles[i + 4] = firstVertex + 3;
|
||||
triangles[i + 5] = firstVertex + 1;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Store triangles.
|
||||
List<Slot> drawOrder = skeleton.DrawOrder;
|
||||
for (int i = startSlot, triangleIndex = 0; i < endSlot; i++) {
|
||||
Attachment attachment = drawOrder[i].attachment;
|
||||
@ -326,11 +353,11 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
attachmentTriangles = quadTriangles;
|
||||
} else if (attachment is MeshAttachment) {
|
||||
MeshAttachment meshAttachment = (MeshAttachment)attachment;
|
||||
attachmentVertexCount = meshAttachment.vertices.Length / 2;
|
||||
attachmentVertexCount = meshAttachment.vertices.Length >> 1;
|
||||
attachmentTriangles = meshAttachment.triangles;
|
||||
} else if (attachment is SkinnedMeshAttachment) {
|
||||
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
||||
attachmentVertexCount = meshAttachment.uvs.Length / 2;
|
||||
attachmentVertexCount = meshAttachment.uvs.Length >> 1;
|
||||
attachmentTriangles = meshAttachment.triangles;
|
||||
} else
|
||||
continue;
|
||||
@ -366,4 +393,5 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
class Submesh {
|
||||
public int[] triangles = new int[0];
|
||||
public int triangleCount;
|
||||
public int firstVertex = -1;
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user