A game about forced loneliness, made by TACStudios
at master 113 lines 4.2 kB view raw
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}