SkeletonCache.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEngine;
  5. namespace UnityEditor.U2D.Animation
  6. {
  7. internal class SkeletonCache : TransformCache
  8. {
  9. [SerializeField]
  10. private bool m_IsPosePreview = false;
  11. [SerializeField]
  12. private List<BoneCache> m_Bones = new List<BoneCache>();
  13. public bool isPosePreview { get { return m_IsPosePreview; } }
  14. public int BoneCount { get { return m_Bones.Count; } }
  15. public virtual BoneCache[] bones
  16. {
  17. get { return m_Bones.ToArray(); }
  18. }
  19. public void AddBone(BoneCache bone)
  20. {
  21. AddBone(bone, true);
  22. }
  23. public void AddBone(BoneCache bone, bool worldPositionStays)
  24. {
  25. Debug.Assert(bone != null);
  26. Debug.Assert(!Contains(bone));
  27. if (bone.parent == null)
  28. bone.SetParent(this, worldPositionStays);
  29. m_Bones.Add(bone);
  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. m_Bones = boneCache.ToList();
  41. }
  42. }
  43. public void DestroyBone(BoneCache bone)
  44. {
  45. Debug.Assert(bone != null);
  46. Debug.Assert(Contains(bone));
  47. m_Bones.Remove(bone);
  48. var children = bone.children;
  49. foreach (var child in children)
  50. child.SetParent(bone.parent);
  51. skinningCache.Destroy(bone);
  52. }
  53. public void SetDefaultPose()
  54. {
  55. foreach (var bone in m_Bones)
  56. bone.SetDefaultPose();
  57. m_IsPosePreview = false;
  58. }
  59. public void RestoreDefaultPose()
  60. {
  61. foreach (var bone in m_Bones)
  62. bone.RestoreDefaultPose();
  63. m_IsPosePreview = false;
  64. skinningCache.events.skeletonPreviewPoseChanged.Invoke(this);
  65. }
  66. public void SetPosePreview()
  67. {
  68. m_IsPosePreview = true;
  69. }
  70. public BonePose[] GetLocalPose()
  71. {
  72. var pose = new List<BonePose>();
  73. foreach (var bone in m_Bones)
  74. pose.Add(bone.localPose);
  75. return pose.ToArray();
  76. }
  77. public void SetLocalPose(BonePose[] pose)
  78. {
  79. Debug.Assert(m_Bones.Count == pose.Length);
  80. for (var i = 0; i < m_Bones.Count; ++i)
  81. m_Bones[i].localPose = pose[i];
  82. m_IsPosePreview = true;
  83. }
  84. public BonePose[] GetWorldPose()
  85. {
  86. var pose = new List<BonePose>();
  87. foreach (var bone in m_Bones)
  88. pose.Add(bone.worldPose);
  89. return pose.ToArray();
  90. }
  91. public void SetWorldPose(BonePose[] pose)
  92. {
  93. Debug.Assert(m_Bones.Count == pose.Length);
  94. for (var i = 0; i < m_Bones.Count; ++i)
  95. {
  96. var bone = m_Bones[i];
  97. var childWoldPose = bone.GetChildrenWoldPose();
  98. bone.worldPose = pose[i];
  99. bone.SetChildrenWorldPose(childWoldPose);
  100. }
  101. m_IsPosePreview = true;
  102. }
  103. public BoneCache GetBone(int index)
  104. {
  105. return m_Bones[index];
  106. }
  107. public int IndexOf(BoneCache bone)
  108. {
  109. return m_Bones.IndexOf(bone);
  110. }
  111. public bool Contains(BoneCache bone)
  112. {
  113. return m_Bones.Contains(bone);
  114. }
  115. public void Clear()
  116. {
  117. var roots = children;
  118. foreach (var root in roots)
  119. DestroyHierarchy(root);
  120. m_Bones.Clear();
  121. }
  122. public string GetUniqueName(BoneCache bone)
  123. {
  124. Debug.Assert(Contains(bone));
  125. var boneName = bone.name;
  126. var names = m_Bones.ConvertAll(b => b.name);
  127. var index = IndexOf(bone);
  128. var count = 0;
  129. Debug.Assert(index < names.Count);
  130. for (var i = 0; i < index; ++i)
  131. if (names[i].Equals(boneName))
  132. ++count;
  133. if (count == 0)
  134. return boneName;
  135. return string.Format("{0} ({1})", boneName, count + 1);
  136. }
  137. private void DestroyHierarchy(TransformCache root)
  138. {
  139. Debug.Assert(root != null);
  140. var children = root.children;
  141. foreach (var child in children)
  142. DestroyHierarchy(child);
  143. skinningCache.Destroy(root);
  144. }
  145. }
  146. }