mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-06 07:14:55 +08:00
Immutable triangles optimization, better inspectors.
This commit is contained in:
parent
10fb67a79c
commit
1306384a8c
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user