Optimization to not render meshes. Better inspectors.

This commit is contained in:
NathanSweet 2014-04-27 00:23:11 +02:00
parent b316b8d3e1
commit 6983ec6fd3
9 changed files with 215 additions and 188 deletions

View File

@ -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();
}
}
}
}

View File

@ -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();
}
}
}

View File

@ -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;
}

View File

@ -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();
}
}
}
}

View File

@ -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();
}
}
}

View File

@ -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;
}