Immutable triangles optimization, better inspectors.

This commit is contained in:
NathanSweet 2014-04-27 13:21:17 +02:00
parent 10fb67a79c
commit 1306384a8c
15 changed files with 119 additions and 113 deletions

View File

@ -47,29 +47,10 @@ public class SkeletonAnimationInspector : SkeletonRendererInspector {
base.gui();
SkeletonAnimation component = (SkeletonAnimation)target;
if (!component.valid) return;
EditorGUILayout.PropertyField(skeletonDataAsset);
if (component.valid) {
// Initial skin name.
String[] skins = new String[component.skeleton.Data.Skins.Count];
int skinIndex = 0;
for (int i = 0; i < skins.Length; i++) {
String name = component.skeleton.Data.Skins[i].Name;
skins[i] = name;
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];
// Animation name.
// Animation name.
{
String[] animations = new String[component.skeleton.Data.Animations.Count + 1];
animations[0] = "<None>";
int animationIndex = 0;
@ -81,19 +62,15 @@ public class SkeletonAnimationInspector : SkeletonRendererInspector {
}
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Animation");
EditorGUIUtility.LookLikeControls();
EditorGUILayout.LabelField("Animation", GUILayout.Width(EditorGUIUtility.labelWidth));
animationIndex = EditorGUILayout.Popup(animationIndex, animations);
EditorGUILayout.EndHorizontal();
component.animationName = animationIndex == 0 ? null : animations[animationIndex];
animationName.stringValue = component.animationName;
String selectedAnimationName = animationIndex == 0 ? null : animations[animationIndex];
component.AnimationName = selectedAnimationName;
animationName.stringValue = selectedAnimationName;
}
// Animation loop.
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Loop");
loop.boolValue = EditorGUILayout.Toggle(loop.boolValue);
EditorGUILayout.EndHorizontal();
EditorGUILayout.PropertyField(loop);
}
}

View File

@ -34,7 +34,7 @@ using UnityEngine;
[CustomEditor(typeof(SkeletonRenderer))]
public class SkeletonRendererInspector : Editor {
protected SerializedProperty skeletonDataAsset, initialSkinName, normals, tangents, meshes;
protected SerializedProperty skeletonDataAsset, initialSkinName, normals, tangents, meshes, immutableTriangles;
protected virtual void OnEnable () {
skeletonDataAsset = serializedObject.FindProperty("skeletonDataAsset");
@ -42,15 +42,29 @@ public class SkeletonRendererInspector : Editor {
normals = serializedObject.FindProperty("calculateNormals");
tangents = serializedObject.FindProperty("calculateTangents");
meshes = serializedObject.FindProperty("renderMeshes");
immutableTriangles = serializedObject.FindProperty("immutableTriangles");
}
protected virtual void gui () {
SkeletonRenderer component = (SkeletonRenderer)target;
EditorGUILayout.PropertyField(skeletonDataAsset);
if (component.valid) {
// Initial skin name.
SkeletonRenderer component = (SkeletonRenderer)target;
if (!component.valid) {
component.Reset();
component.LateUpdate();
if (!component.valid) {
EditorGUILayout.BeginHorizontal();
EditorGUILayout.Space();
if (GUILayout.Button("Refresh")) component.Reset();
EditorGUILayout.Space();
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
return;
}
}
// Initial skin name.
{
String[] skins = new String[component.skeleton.Data.Skins.Count];
int skinIndex = 0;
for (int i = 0; i < skins.Length; i++) {
@ -61,15 +75,17 @@ public class SkeletonRendererInspector : Editor {
}
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Initial Skin");
EditorGUIUtility.LookLikeControls();
EditorGUILayout.LabelField("Initial Skin", GUILayout.Width(EditorGUIUtility.labelWidth));
skinIndex = EditorGUILayout.Popup(skinIndex, skins);
EditorGUILayout.EndHorizontal();
initialSkinName.stringValue = skins[skinIndex];
}
EditorGUILayout.PropertyField(meshes);
EditorGUILayout.PropertyField(meshes,
new GUIContent("Render Meshes", "Disable to optimize rendering for skeletons that don't use meshes"));
EditorGUILayout.PropertyField(immutableTriangles,
new GUIContent("Immutable Triangles", "Enable to optimize rendering for skeletons that never change attachment visbility"));
EditorGUILayout.PropertyField(normals);
EditorGUILayout.PropertyField(tangents);
}

View File

@ -44,8 +44,9 @@ public class SkeletonAnimation : SkeletonRenderer {
public delegate void UpdateBonesDelegate(SkeletonAnimation skeleton);
public UpdateBonesDelegate UpdateBones;
public String _animationName;
public String animationName {
[SerializeField]
private String _animationName;
public String AnimationName {
get {
TrackEntry entry = state.GetCurrent(0);
return entry == null ? null : entry.Animation.Name;

View File

@ -44,10 +44,9 @@ public class SkeletonRenderer : MonoBehaviour {
public SkeletonDataAsset skeletonDataAsset;
public String initialSkinName;
public bool calculateNormals;
public bool calculateTangents;
public bool calculateNormals, calculateTangents;
public float zSpacing;
public bool renderMeshes;
public bool renderMeshes = true, immutableTriangles;
private MeshFilter meshFilter;
private Mesh mesh, mesh1, mesh2;
@ -60,8 +59,7 @@ public class SkeletonRenderer : MonoBehaviour {
private Material[] sharedMaterials = new Material[0];
private readonly List<Material> submeshMaterials = new List<Material>();
private readonly List<Submesh> submeshes = new List<Submesh>();
private readonly int[] quadTriangles = {0, 2, 1, 2, 3, 1};
public virtual void Reset () {
if (meshFilter != null) meshFilter.sharedMesh = null;
if (mesh != null) DestroyImmediate(mesh);
@ -111,7 +109,7 @@ public class SkeletonRenderer : MonoBehaviour {
public virtual void LateUpdate () {
if (!valid) return;
// Count vertices and submesh triangles.
int vertexCount = 0;
int submeshTriangleCount = 0, submeshFirstVertex = 0, submeshStartSlotIndex = 0;
@ -280,8 +278,7 @@ public class SkeletonRenderer : MonoBehaviour {
mesh.subMeshCount = submeshCount;
for (int i = 0; i < submeshCount; ++i)
mesh.SetTriangles(submeshes[i].triangles, i);
mesh.RecalculateBounds();
if (newTriangles && calculateNormals) {
Vector3[] normals = new Vector3[vertexCount];
Vector3 normal = new Vector3(0, 0, -1);
@ -309,7 +306,11 @@ public class SkeletonRenderer : MonoBehaviour {
int submeshIndex = submeshMaterials.Count;
submeshMaterials.Add(material);
if (submeshes.Count <= submeshIndex) submeshes.Add(new Submesh());
if (submeshes.Count <= submeshIndex)
submeshes.Add(new Submesh());
else if (immutableTriangles)
return;
Submesh submesh = submeshes[submeshIndex];
int[] triangles = submesh.triangles;
@ -346,12 +347,20 @@ public class SkeletonRenderer : MonoBehaviour {
List<Slot> drawOrder = skeleton.DrawOrder;
for (int i = startSlot, triangleIndex = 0; i < endSlot; i++) {
Attachment attachment = drawOrder[i].attachment;
if (attachment is RegionAttachment) {
triangles[triangleIndex] = firstVertex;
triangles[triangleIndex + 1] = firstVertex + 2;
triangles[triangleIndex + 2] = firstVertex + 1;
triangles[triangleIndex + 3] = firstVertex + 2;
triangles[triangleIndex + 4] = firstVertex + 3;
triangles[triangleIndex + 5] = firstVertex + 1;
triangleIndex += 6;
firstVertex += 4;
continue;
}
int[] attachmentTriangles;
int attachmentVertexCount;
if (attachment is RegionAttachment) {
attachmentVertexCount = 4;
attachmentTriangles = quadTriangles;
} else if (attachment is MeshAttachment) {
if (attachment is MeshAttachment) {
MeshAttachment meshAttachment = (MeshAttachment)attachment;
attachmentVertexCount = meshAttachment.vertices.Length >> 1;
attachmentTriangles = meshAttachment.triangles;
@ -376,8 +385,8 @@ public class SkeletonRenderer : MonoBehaviour {
Vector3 min = new Vector3(float.MaxValue, float.MaxValue, 0f);
Vector3 max = new Vector3(float.MinValue, float.MinValue, 0f);
foreach (Vector3 vert in vertices) {
min = Vector3.Min (min, vert);
max = Vector3.Max (max, vert);
min = Vector3.Min(min, vert);
max = Vector3.Max(max, vert);
}
float width = max.x - min.x;
float height = max.y - min.y;

View File

@ -47,29 +47,10 @@ public class SkeletonAnimationInspector : SkeletonRendererInspector {
base.gui();
SkeletonAnimation component = (SkeletonAnimation)target;
if (!component.valid) return;
EditorGUILayout.PropertyField(skeletonDataAsset);
if (component.valid) {
// Initial skin name.
String[] skins = new String[component.skeleton.Data.Skins.Count];
int skinIndex = 0;
for (int i = 0; i < skins.Length; i++) {
String name = component.skeleton.Data.Skins[i].Name;
skins[i] = name;
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];
// Animation name.
// Animation name.
{
String[] animations = new String[component.skeleton.Data.Animations.Count + 1];
animations[0] = "<None>";
int animationIndex = 0;
@ -81,19 +62,15 @@ public class SkeletonAnimationInspector : SkeletonRendererInspector {
}
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Animation");
EditorGUIUtility.LookLikeControls();
EditorGUILayout.LabelField("Animation", GUILayout.Width(EditorGUIUtility.labelWidth));
animationIndex = EditorGUILayout.Popup(animationIndex, animations);
EditorGUILayout.EndHorizontal();
component.animationName = animationIndex == 0 ? null : animations[animationIndex];
animationName.stringValue = component.animationName;
String selectedAnimationName = animationIndex == 0 ? null : animations[animationIndex];
component.AnimationName = selectedAnimationName;
animationName.stringValue = selectedAnimationName;
}
// Animation loop.
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Loop");
loop.boolValue = EditorGUILayout.Toggle(loop.boolValue);
EditorGUILayout.EndHorizontal();
EditorGUILayout.PropertyField(loop);
}
}

View File

@ -34,7 +34,7 @@ using UnityEngine;
[CustomEditor(typeof(SkeletonRenderer))]
public class SkeletonRendererInspector : Editor {
protected SerializedProperty skeletonDataAsset, initialSkinName, normals, tangents, meshes;
protected SerializedProperty skeletonDataAsset, initialSkinName, normals, tangents, meshes, immutableTriangles;
protected virtual void OnEnable () {
skeletonDataAsset = serializedObject.FindProperty("skeletonDataAsset");
@ -42,15 +42,29 @@ public class SkeletonRendererInspector : Editor {
normals = serializedObject.FindProperty("calculateNormals");
tangents = serializedObject.FindProperty("calculateTangents");
meshes = serializedObject.FindProperty("renderMeshes");
immutableTriangles = serializedObject.FindProperty("immutableTriangles");
}
protected virtual void gui () {
SkeletonRenderer component = (SkeletonRenderer)target;
EditorGUILayout.PropertyField(skeletonDataAsset);
if (component.valid) {
// Initial skin name.
SkeletonRenderer component = (SkeletonRenderer)target;
if (!component.valid) {
component.Reset();
component.LateUpdate();
if (!component.valid) {
EditorGUILayout.BeginHorizontal();
EditorGUILayout.Space();
if (GUILayout.Button("Refresh")) component.Reset();
EditorGUILayout.Space();
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
return;
}
}
// Initial skin name.
{
String[] skins = new String[component.skeleton.Data.Skins.Count];
int skinIndex = 0;
for (int i = 0; i < skins.Length; i++) {
@ -61,15 +75,17 @@ public class SkeletonRendererInspector : Editor {
}
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Initial Skin");
EditorGUIUtility.LookLikeControls();
EditorGUILayout.LabelField("Initial Skin", GUILayout.Width(EditorGUIUtility.labelWidth));
skinIndex = EditorGUILayout.Popup(skinIndex, skins);
EditorGUILayout.EndHorizontal();
initialSkinName.stringValue = skins[skinIndex];
}
EditorGUILayout.PropertyField(meshes);
EditorGUILayout.PropertyField(meshes,
new GUIContent("Render Meshes", "Disable to optimize rendering for skeletons that don't use meshes"));
EditorGUILayout.PropertyField(immutableTriangles,
new GUIContent("Immutable Triangles", "Enable to optimize rendering for skeletons that never change attachment visbility"));
EditorGUILayout.PropertyField(normals);
EditorGUILayout.PropertyField(tangents);
}

View File

@ -44,8 +44,9 @@ public class SkeletonAnimation : SkeletonRenderer {
public delegate void UpdateBonesDelegate(SkeletonAnimation skeleton);
public UpdateBonesDelegate UpdateBones;
public String _animationName;
public String animationName {
[SerializeField]
private String _animationName;
public String AnimationName {
get {
TrackEntry entry = state.GetCurrent(0);
return entry == null ? null : entry.Animation.Name;

View File

@ -44,10 +44,9 @@ public class SkeletonRenderer : MonoBehaviour {
public SkeletonDataAsset skeletonDataAsset;
public String initialSkinName;
public bool calculateNormals;
public bool calculateTangents;
public bool calculateNormals, calculateTangents;
public float zSpacing;
public bool renderMeshes;
public bool renderMeshes = true, immutableTriangles;
private MeshFilter meshFilter;
private Mesh mesh, mesh1, mesh2;
@ -60,8 +59,7 @@ public class SkeletonRenderer : MonoBehaviour {
private Material[] sharedMaterials = new Material[0];
private readonly List<Material> submeshMaterials = new List<Material>();
private readonly List<Submesh> submeshes = new List<Submesh>();
private readonly int[] quadTriangles = {0, 2, 1, 2, 3, 1};
public virtual void Reset () {
if (meshFilter != null) meshFilter.sharedMesh = null;
if (mesh != null) DestroyImmediate(mesh);
@ -280,8 +278,7 @@ public class SkeletonRenderer : MonoBehaviour {
mesh.subMeshCount = submeshCount;
for (int i = 0; i < submeshCount; ++i)
mesh.SetTriangles(submeshes[i].triangles, i);
mesh.RecalculateBounds();
if (newTriangles && calculateNormals) {
Vector3[] normals = new Vector3[vertexCount];
Vector3 normal = new Vector3(0, 0, -1);
@ -309,7 +306,11 @@ public class SkeletonRenderer : MonoBehaviour {
int submeshIndex = submeshMaterials.Count;
submeshMaterials.Add(material);
if (submeshes.Count <= submeshIndex) submeshes.Add(new Submesh());
if (submeshes.Count <= submeshIndex)
submeshes.Add(new Submesh());
else if (immutableTriangles)
return;
Submesh submesh = submeshes[submeshIndex];
int[] triangles = submesh.triangles;
@ -346,12 +347,20 @@ public class SkeletonRenderer : MonoBehaviour {
List<Slot> drawOrder = skeleton.DrawOrder;
for (int i = startSlot, triangleIndex = 0; i < endSlot; i++) {
Attachment attachment = drawOrder[i].attachment;
if (attachment is RegionAttachment) {
triangles[triangleIndex] = firstVertex;
triangles[triangleIndex + 1] = firstVertex + 2;
triangles[triangleIndex + 2] = firstVertex + 1;
triangles[triangleIndex + 3] = firstVertex + 2;
triangles[triangleIndex + 4] = firstVertex + 3;
triangles[triangleIndex + 5] = firstVertex + 1;
triangleIndex += 6;
firstVertex += 4;
continue;
}
int[] attachmentTriangles;
int attachmentVertexCount;
if (attachment is RegionAttachment) {
attachmentVertexCount = 4;
attachmentTriangles = quadTriangles;
} else if (attachment is MeshAttachment) {
if (attachment is MeshAttachment) {
MeshAttachment meshAttachment = (MeshAttachment)attachment;
attachmentVertexCount = meshAttachment.vertices.Length >> 1;
attachmentTriangles = meshAttachment.triangles;
@ -376,8 +385,8 @@ public class SkeletonRenderer : MonoBehaviour {
Vector3 min = new Vector3(float.MaxValue, float.MaxValue, 0f);
Vector3 max = new Vector3(float.MinValue, float.MinValue, 0f);
foreach (Vector3 vert in vertices) {
min = Vector3.Min (min, vert);
max = Vector3.Max (max, vert);
min = Vector3.Min(min, vert);
max = Vector3.Max(max, vert);
}
float width = max.x - min.x;
float height = max.y - min.y;