A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections.Generic;
3using UnityEditor.U2D.Sprites;
4using UnityEngine;
5
6namespace UnityEditor.U2D.Animation
7{
8 [Serializable]
9 internal class MeshCache : BaseSpriteMeshData
10 {
11 [SerializeField]
12 List<BoneCache> m_Bones = new List<BoneCache>();
13 [SerializeField]
14 SpriteCache m_Sprite;
15
16 public override string spriteName => sprite.name;
17 public override int boneCount => m_Bones.Count;
18 public override Rect frame => sprite.textureRect;
19
20 public ITextureDataProvider textureDataProvider { get; set; }
21
22 public SpriteCache sprite
23 {
24 get => m_Sprite;
25 set => m_Sprite = value;
26 }
27
28 public BoneCache[] bones
29 {
30 get => m_Bones.ToArray();
31 set => SetBones(value);
32 }
33
34 public override SpriteBoneData GetBoneData(int index)
35 {
36 var worldToLocalMatrix = sprite.worldToLocalMatrix;
37
38 //We expect m_Bones to contain character's bones references if character exists. Sprite's skeleton bones otherwise.
39 if (sprite.skinningCache.hasCharacter)
40 worldToLocalMatrix = sprite.GetCharacterPart().worldToLocalMatrix;
41
42 SpriteBoneData spriteBoneData;
43 var bone = m_Bones[index];
44
45 if (bone == null)
46 spriteBoneData = new SpriteBoneData();
47 else
48 {
49 spriteBoneData = new SpriteBoneData()
50 {
51 parentId = bone.parentBone == null ? -1 : m_Bones.IndexOf(bone.parentBone),
52 localPosition = bone.localPosition,
53 localRotation = bone.localRotation,
54 position = worldToLocalMatrix.MultiplyPoint3x4(bone.position),
55 endPosition = worldToLocalMatrix.MultiplyPoint3x4(bone.endPosition),
56 depth = bone.depth,
57 length = bone.localLength
58 };
59 }
60
61 return spriteBoneData;
62 }
63
64 public override float GetBoneDepth(int index)
65 {
66 return m_Bones[index].depth;
67 }
68
69 public bool ContainsBone(BoneCache bone)
70 {
71 return m_Bones.Contains(bone);
72 }
73
74 public void SetCompatibleBoneSet(BoneCache[] boneCache)
75 {
76 m_Bones = new List<BoneCache>(boneCache);
77 }
78
79 void SetBones(BoneCache[] boneCache)
80 {
81 FixWeights(boneCache);
82 SetCompatibleBoneSet(boneCache);
83 }
84
85 void FixWeights(BoneCache[] newBones)
86 {
87 var newBonesList = new List<BoneCache>(newBones);
88 var indexMap = new Dictionary<int, int>();
89
90 for (var i = 0; i < m_Bones.Count; ++i)
91 {
92 var bone = m_Bones[i];
93 var newIndex = newBonesList.IndexOf(bone);
94
95 if (newIndex != -1)
96 indexMap.Add(i, newIndex);
97 }
98
99 for (var i = 0; i < vertexWeights.Length; ++i)
100 {
101 var boneWeight = vertexWeights[i];
102 for (var m = 0; m < boneWeight.Count; ++m)
103 {
104 var boneRemoved = indexMap.TryGetValue(boneWeight[m].boneIndex, out var newIndex) == false;
105
106 if (boneRemoved)
107 {
108 boneWeight[m].weight = 0f;
109 boneWeight[m].enabled = false;
110 }
111
112 boneWeight[m].boneIndex = newIndex;
113
114 if (boneRemoved)
115 boneWeight.CompensateOtherChannels(m);
116 }
117
118 boneWeight.UnifyChannelsWithSameBoneIndex();
119 vertexWeights[i] = boneWeight;
120 }
121 }
122 }
123}