A game about forced loneliness, made by TACStudios
at master 180 lines 4.6 kB view raw
1using System.Collections.Generic; 2using System.Linq; 3using UnityEngine; 4 5namespace UnityEditor.U2D.Animation 6{ 7 internal class SkeletonCache : TransformCache 8 { 9 [SerializeField] 10 bool m_IsPosePreview = false; 11 [SerializeField] 12 List<BoneCache> m_Bones = new List<BoneCache>(); 13 14 public bool isPosePreview => m_IsPosePreview; 15 16 public int boneCount => m_Bones.Count; 17 18 public virtual BoneCache[] bones => m_Bones.ToArray(); 19 20 public void AddBone(BoneCache bone, bool worldPositionStays = true) 21 { 22 Debug.Assert(bone != null); 23 Debug.Assert(!Contains(bone)); 24 25 if (bone.parent == null) 26 bone.SetParent(this, worldPositionStays); 27 28 m_Bones.Add(bone); 29 } 30 31 public void ReorderBones(IEnumerable<BoneCache> boneCache) 32 { 33 if (boneCache.Count() == m_Bones.Count) 34 { 35 foreach (var b in m_Bones) 36 { 37 if (!boneCache.Contains(b)) 38 return; 39 } 40 41 m_Bones = boneCache.ToList(); 42 } 43 } 44 45 public void DestroyBone(BoneCache bone) 46 { 47 Debug.Assert(bone != null); 48 Debug.Assert(Contains(bone)); 49 50 m_Bones.Remove(bone); 51 52 var boneChildren = bone.children; 53 foreach (var child in boneChildren) 54 child.SetParent(bone.parent); 55 56 skinningCache.Destroy(bone); 57 } 58 59 public void SetDefaultPose() 60 { 61 foreach (var bone in m_Bones) 62 bone.SetDefaultPose(); 63 64 m_IsPosePreview = false; 65 } 66 67 public void RestoreDefaultPose() 68 { 69 foreach (var bone in m_Bones) 70 bone.RestoreDefaultPose(); 71 72 m_IsPosePreview = false; 73 skinningCache.events.skeletonPreviewPoseChanged.Invoke(this); 74 } 75 76 public void SetPosePreview() 77 { 78 m_IsPosePreview = true; 79 } 80 81 public BonePose[] GetLocalPose() 82 { 83 var pose = new List<BonePose>(); 84 85 foreach (var bone in m_Bones) 86 pose.Add(bone.localPose); 87 88 return pose.ToArray(); 89 } 90 91 public void SetLocalPose(BonePose[] pose) 92 { 93 Debug.Assert(m_Bones.Count == pose.Length); 94 95 for (var i = 0; i < m_Bones.Count; ++i) 96 m_Bones[i].localPose = pose[i]; 97 98 m_IsPosePreview = true; 99 } 100 101 public BonePose[] GetWorldPose() 102 { 103 var pose = new List<BonePose>(); 104 105 foreach (var bone in m_Bones) 106 pose.Add(bone.worldPose); 107 108 return pose.ToArray(); 109 } 110 111 public void SetWorldPose(BonePose[] pose) 112 { 113 Debug.Assert(m_Bones.Count == pose.Length); 114 115 for (var i = 0; i < m_Bones.Count; ++i) 116 { 117 var bone = m_Bones[i]; 118 var childWoldPose = bone.GetChildrenWoldPose(); 119 bone.worldPose = pose[i]; 120 bone.SetChildrenWorldPose(childWoldPose); 121 } 122 123 m_IsPosePreview = true; 124 } 125 126 public BoneCache GetBone(int index) 127 { 128 return m_Bones[index]; 129 } 130 131 public int IndexOf(BoneCache bone) 132 { 133 return m_Bones.IndexOf(bone); 134 } 135 136 public bool Contains(BoneCache bone) 137 { 138 return m_Bones.Contains(bone); 139 } 140 141 public void Clear() 142 { 143 var roots = children; 144 145 foreach (var root in roots) 146 DestroyHierarchy(root); 147 148 m_Bones.Clear(); 149 } 150 151 public string GetUniqueName(BoneCache bone) 152 { 153 Debug.Assert(Contains(bone)); 154 155 var boneName = bone.name; 156 var names = m_Bones.ConvertAll(b => b.name); 157 var index = IndexOf(bone); 158 var count = 0; 159 160 Debug.Assert(index < names.Count); 161 162 for (var i = 0; i < index; ++i) 163 if (names[i].Equals(boneName)) 164 ++count; 165 166 return count == 0 ? boneName : $"{boneName} ({count + 1})"; 167 } 168 169 void DestroyHierarchy(TransformCache root) 170 { 171 Debug.Assert(root != null); 172 173 var rootChildren = root.children; 174 foreach (var child in rootChildren) 175 DestroyHierarchy(child); 176 177 skinningCache.Destroy(root); 178 } 179 } 180}