MeshCache.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. using System.Collections.Generic;
  2. using UnityEditor.U2D.Sprites;
  3. using UnityEngine;
  4. namespace UnityEditor.U2D.Animation
  5. {
  6. internal class MeshCache : SkinningObject, ISpriteMeshData
  7. {
  8. [SerializeField]
  9. private SpriteCache m_Sprite;
  10. [SerializeField]
  11. private List<Vertex2D> m_Vertices = new List<Vertex2D>();
  12. [SerializeField]
  13. private List<int> m_Indices = new List<int>();
  14. [SerializeField]
  15. private List<Edge> m_Edges = new List<Edge>();
  16. [SerializeField]
  17. private List<BoneCache> m_Bones = new List<BoneCache>();
  18. public ITextureDataProvider textureDataProvider { get; set; }
  19. public SpriteCache sprite
  20. {
  21. get { return m_Sprite; }
  22. set { m_Sprite = value; }
  23. }
  24. public List<Vertex2D> vertices
  25. {
  26. get { return m_Vertices; }
  27. set { m_Vertices = value; }
  28. }
  29. public List<Vector3> vertexPositionOverride { get; set; }
  30. public List<Edge> edges
  31. {
  32. get { return m_Edges; }
  33. set { m_Edges = value; }
  34. }
  35. public List<int> indices
  36. {
  37. get { return m_Indices; }
  38. set { m_Indices = value; }
  39. }
  40. public BoneCache[] bones
  41. {
  42. get { return m_Bones.ToArray(); }
  43. set { SetBones(value); }
  44. }
  45. Rect ISpriteMeshData.frame
  46. {
  47. get { return sprite.textureRect; }
  48. set {}
  49. }
  50. public int vertexCount
  51. {
  52. get { return m_Vertices.Count; }
  53. }
  54. public int boneCount
  55. {
  56. get { return m_Bones.Count; }
  57. }
  58. public Vector2 GetPosition(int index)
  59. {
  60. if (vertexPositionOverride != null)
  61. return vertexPositionOverride[index];
  62. return m_Vertices[index].position;
  63. }
  64. public void SetPosition(int index, Vector2 position)
  65. {
  66. if (vertexPositionOverride != null)
  67. return;
  68. m_Vertices[index].position = position;
  69. }
  70. public EditableBoneWeight GetWeight(int index)
  71. {
  72. return m_Vertices[index].editableBoneWeight;
  73. }
  74. public void SetWeight(int index, EditableBoneWeight weight)
  75. {
  76. m_Vertices[index].editableBoneWeight = weight;
  77. }
  78. public void AddVertex(Vector2 position, BoneWeight weight)
  79. {
  80. m_Vertices.Add(new Vertex2D(position, weight));
  81. }
  82. public void RemoveVertex(int index)
  83. {
  84. m_Vertices.RemoveAt(index);
  85. }
  86. SpriteBoneData ISpriteMeshData.GetBoneData(int index)
  87. {
  88. var worldToLocalMatrix = sprite.worldToLocalMatrix;
  89. //We expect m_Bones to contain character's bones references if character exists. Sprite's skeleton bones otherwise.
  90. if (skinningCache.hasCharacter)
  91. worldToLocalMatrix = sprite.GetCharacterPart().worldToLocalMatrix;
  92. SpriteBoneData spriteBoneData = null;
  93. var bone = m_Bones[index];
  94. if (bone == null)
  95. spriteBoneData = new SpriteBoneData();
  96. else
  97. {
  98. spriteBoneData = new SpriteBoneData()
  99. {
  100. name = bone.name,
  101. parentId = bone.parentBone == null ? -1 : m_Bones.IndexOf(bone.parentBone),
  102. localPosition = bone.localPosition,
  103. localRotation = bone.localRotation,
  104. position = worldToLocalMatrix.MultiplyPoint3x4(bone.position),
  105. endPosition = worldToLocalMatrix.MultiplyPoint3x4(bone.endPosition),
  106. depth = bone.depth,
  107. length = bone.localLength
  108. };
  109. }
  110. return spriteBoneData;
  111. }
  112. float ISpriteMeshData.GetBoneDepth(int index)
  113. {
  114. return m_Bones[index].depth;
  115. }
  116. public void Clear()
  117. {
  118. m_Vertices.Clear();
  119. m_Indices.Clear();
  120. m_Edges.Clear();
  121. }
  122. public bool ContainsBone(BoneCache bone)
  123. {
  124. return m_Bones.Contains(bone);
  125. }
  126. public void SetCompatibleBoneSet(BoneCache[] bones)
  127. {
  128. m_Bones = new List<BoneCache>(bones);
  129. }
  130. private void SetBones(BoneCache[] bones)
  131. {
  132. FixWeights(bones);
  133. SetCompatibleBoneSet(bones);
  134. }
  135. private void FixWeights(BoneCache[] newBones)
  136. {
  137. var newBonesList = new List<BoneCache>(newBones);
  138. var indexMap = new Dictionary<int, int>();
  139. for (var i = 0; i < m_Bones.Count; ++i)
  140. {
  141. var bone = m_Bones[i];
  142. var newIndex = newBonesList.IndexOf(bone);
  143. if (newIndex != -1)
  144. indexMap.Add(i, newIndex);
  145. }
  146. foreach (Vertex2D vertex in vertices)
  147. {
  148. var boneWeight = vertex.editableBoneWeight;
  149. for (var i = 0; i < boneWeight.Count; ++i)
  150. {
  151. var newIndex = 0;
  152. var boneRemoved = indexMap.TryGetValue(boneWeight[i].boneIndex, out newIndex) == false;
  153. if (boneRemoved)
  154. {
  155. boneWeight[i].weight = 0f;
  156. boneWeight[i].enabled = false;
  157. }
  158. boneWeight[i].boneIndex = newIndex;
  159. if (boneRemoved)
  160. boneWeight.CompensateOtherChannels(i);
  161. }
  162. boneWeight.UnifyChannelsWithSameBoneIndex();
  163. }
  164. }
  165. }
  166. }