A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections.Generic;
3using UnityEngine;
4
5namespace UnityEditor.U2D.Animation
6{
7 internal class SmoothingUtility
8 {
9 private static float[,] m_DataInTemp;
10 private static float[,] m_DataOutTemp;
11 private static float[] m_DenominatorTemp;
12 private static EditableBoneWeight s_BoneWeight = new EditableBoneWeight();
13
14 public static void SmoothWeights(BoneWeight[] boneWeightIn, IList<int> indices, int boneCount, out BoneWeight[] boneWeightOut)
15 {
16 SmoothWeights(boneWeightIn, indices, boneCount, 1, out boneWeightOut);
17 }
18
19 public static void SmoothWeights(BoneWeight[] boneWeightIn, IList<int> indices, int boneCount, int iterations, out BoneWeight[] boneWeightOut)
20 {
21 Debug.Assert(boneWeightIn != null);
22
23 boneWeightOut = new BoneWeight[boneWeightIn.Length];
24
25 PrepareTempBuffers(boneWeightIn.Length, boneCount);
26
27 for (int i = 0; i < boneWeightIn.Length; ++i)
28 {
29 s_BoneWeight.SetFromBoneWeight(boneWeightIn[i]);
30 for (var j = 0; j < s_BoneWeight.Count; ++j)
31 {
32 if (s_BoneWeight[j].enabled)
33 m_DataInTemp[i, s_BoneWeight[j].boneIndex] = s_BoneWeight[j].weight;
34 }
35 }
36
37 for (var i = 0; i < iterations; ++i)
38 SmoothPerVertexData(indices, m_DataInTemp, m_DataOutTemp);
39
40 for (var i = 0; i < boneWeightIn.Length; ++i)
41 {
42 s_BoneWeight.Clear();
43
44 for (var j = 0; j < boneCount; ++j)
45 {
46 var weight = m_DataOutTemp[i, j];
47 var boneIndex = weight > 0f ? j : 0;
48 s_BoneWeight.AddChannel(boneIndex, weight, weight > 0);
49 }
50
51 s_BoneWeight.Clamp(4);
52 s_BoneWeight.Normalize();
53
54 boneWeightOut[i] = s_BoneWeight.ToBoneWeight(false);
55 }
56 }
57
58 public static void SmoothPerVertexData(IList<int> indices, float[,] dataIn, float[,] dataOut)
59 {
60 Debug.Assert(dataIn != null);
61 Debug.Assert(dataOut != null);
62 Debug.Assert(dataIn != dataOut);
63 Debug.Assert(dataIn.Length == dataOut.Length);
64
65 int rowLength = dataIn.GetLength(0);
66 int colLength = dataIn.GetLength(1);
67
68 PrepareDenominatorBuffer(rowLength);
69
70 for (int i = 0; i < indices.Count / 3; ++i)
71 {
72 for (int j = 0; j < 3; ++j)
73 {
74 int j1 = (j + 1) % 3;
75 int j2 = (j + 2) % 3;
76
77 for (int k = 0; k < colLength; ++k)
78 dataOut[indices[i * 3 + j], k] += dataIn[indices[i * 3 + j1], k] + dataIn[indices[i * 3 + j2], k];
79
80 m_DenominatorTemp[indices[i * 3 + j]] += 2;
81 }
82 }
83
84 for (int i = 0; i < rowLength; ++i)
85 {
86 var dInv = 1f / Mathf.Max(1f, m_DenominatorTemp[i]);
87 for (int j = 0; j < colLength; ++j)
88 dataOut[i, j] *= dInv;
89 }
90 }
91
92 private static void PrepareDenominatorBuffer(int rowLength)
93 {
94 if (m_DenominatorTemp == null || m_DenominatorTemp.Length != rowLength)
95 m_DenominatorTemp = new float[rowLength];
96 else
97 Array.Clear(m_DenominatorTemp, 0, m_DenominatorTemp.Length);
98 }
99
100 private static void PrepareTempBuffers(int rowLength, int colLength)
101 {
102 if (m_DataInTemp == null || m_DataInTemp.GetLength(0) != rowLength || m_DataInTemp.GetLength(1) != colLength)
103 m_DataInTemp = new float[rowLength, colLength];
104 else
105 Array.Clear(m_DataInTemp, 0, m_DataInTemp.Length);
106
107 if (m_DataOutTemp == null || m_DataOutTemp.GetLength(0) != rowLength || m_DataOutTemp.GetLength(1) != colLength)
108 m_DataOutTemp = new float[rowLength, colLength];
109 else
110 Array.Clear(m_DataOutTemp, 0, m_DataOutTemp.Length);
111 }
112 }
113}