Ejemplo n.º 1
0
        protected override void DoWindow(int windowId)
        {
            float labelWidth = EditorGUIUtility.labelWidth;
            bool  wideMode   = EditorGUIUtility.wideMode;

            EditorGUIUtility.wideMode = true;

            EditorGUILayout.BeginHorizontal();

            string[] names = spriteMeshCache.GetBoneNames("None");
            int      index = spriteMeshCache.bindPoses.IndexOf(spriteMeshCache.selectedBindPose);

            index = EditorGUILayout.Popup(index + 1, names, GUILayout.Width(75f)) - 1;

            if (index >= 0 && index < spriteMeshCache.bindPoses.Count)
            {
                spriteMeshCache.selectedBindPose = spriteMeshCache.bindPoses[index];
            }
            else
            {
                spriteMeshCache.selectedBindPose = null;
            }

            EditorGUI.BeginChangeCheck();

            EditorGUI.BeginDisabledGroup(spriteMeshCache.selectedBindPose == null);

            if (Event.current.type == EventType.MouseUp ||
                Event.current.type == EventType.MouseDown)
            {
                m_Weight = 0f;

                m_TempWeights.Clear();

                if (spriteMeshCache.selection.Count == 0)
                {
                    m_TempWeights = spriteMeshCache.boneWeights.ToList();
                }
                else
                {
                    m_TempWeights = spriteMeshCache.selectedNodes.ConvertAll(n => spriteMeshCache.GetBoneWeight(n));
                }
            }

            EditorGUIUtility.fieldWidth = 35f;

            m_Weight = EditorGUILayout.Slider(m_Weight, -1f, 1f);

            EditorGUIUtility.fieldWidth = 0f;

            if (EditorGUI.EndChangeCheck())
            {
                spriteMeshCache.RegisterUndo("modify weights");

                List <Node> nodes = null;

                if (spriteMeshCache.selection.Count == 0)
                {
                    nodes = spriteMeshCache.nodes;
                }
                else
                {
                    nodes = spriteMeshCache.selectedNodes;
                }

                for (int i = 0; i < nodes.Count; i++)
                {
                    Node       node       = nodes[i];
                    BoneWeight tempWeight = m_TempWeights[i];
                    tempWeight.SetBoneIndexWeight(index, tempWeight.GetBoneWeight(index) + m_Weight, !EditorGUI.actionKey, true);
                    spriteMeshCache.SetBoneWeight(node, tempWeight);
                }
            }

            EditorGUI.EndDisabledGroup();

            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            if (GUILayout.Button(new GUIContent("Smooth", "Smooth weights")))
            {
                spriteMeshCache.RegisterUndo("smooth weights");

                List <Node> targetNodes = spriteMeshCache.nodes;

                if (spriteMeshCache.selection.Count > 0)
                {
                    targetNodes = spriteMeshCache.selectedNodes;
                }

                spriteMeshCache.SmoothWeights(targetNodes);
            }

            if (GUILayout.Button(new GUIContent("Auto", "Calculate automatic weights")))
            {
                spriteMeshCache.RegisterUndo("calculate weights");

                List <Node> targetNodes = spriteMeshCache.nodes;

                if (spriteMeshCache.selection.Count > 0)
                {
                    targetNodes = spriteMeshCache.selectedNodes;
                }

                spriteMeshCache.CalculateAutomaticWeights(targetNodes);
            }

            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();

            EditorGUIUtility.labelWidth = 50f;

            overlayColors = EditorGUILayout.Toggle("Overlay", overlayColors);

            EditorGUIUtility.labelWidth = 30f;

            showPie = EditorGUILayout.Toggle("Pies", showPie);

            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();

            EditorGUIUtility.labelWidth = labelWidth;
            EditorGUIUtility.wideMode   = wideMode;
        }
Ejemplo n.º 2
0
        public void CalculateAutomaticWeights(List <Node> targetNodes)
        {
            float pixelsPerUnit = SpriteMeshUtils.GetSpritePixelsPerUnit(spriteMesh.sprite);

            if (nodes.Count <= 0)
            {
                Debug.Log("Cannot calculate automatic weights from a SpriteMesh with no vertices.");
                return;
            }

            if (bindPoses.Count <= 0)
            {
                Debug.Log("Cannot calculate automatic weights. Specify bones to the SpriteMeshInstance.");
                return;
            }

            if (spriteMesh && bindPoses.Count > 1)
            {
                List <Vector2>     controlPoints     = new List <Vector2>(bindPoses.Count * 2);
                List <IndexedEdge> controlPointEdges = new List <IndexedEdge>(bindPoses.Count);

                foreach (BindInfo bindInfo in bindPoses)
                {
                    Vector2 tip  = SpriteMeshUtils.VertexToTexCoord(spriteMesh, pivotPoint, bindInfo.position, pixelsPerUnit);
                    Vector2 tail = SpriteMeshUtils.VertexToTexCoord(spriteMesh, pivotPoint, bindInfo.endPoint, pixelsPerUnit);

                    int index1 = -1;

                    if (!ContainsVector(tip, controlPoints, 0.01f, out index1))
                    {
                        index1 = controlPoints.Count;
                        controlPoints.Add(tip);
                    }

                    int index2 = -1;

                    if (!ContainsVector(tail, controlPoints, 0.01f, out index2))
                    {
                        index2 = controlPoints.Count;
                        controlPoints.Add(tail);
                    }

                    IndexedEdge edge = new IndexedEdge(index1, index2);
                    controlPointEdges.Add(edge);
                }

                float[,] weightArray;

                BbwPlugin.CalculateBbw(m_TexVertices.ToArray(),
                                       indexedEdges.ToArray(),
                                       controlPoints.ToArray(),
                                       controlPointEdges.ToArray(),
                                       out weightArray);

                FillBoneWeights(targetNodes, weightArray);

                isDirty = true;
            }
            else
            {
                BoneWeight boneWeight = BoneWeight.Create();
                boneWeight.boneIndex0 = 0;
                boneWeight.weight0    = 1f;

                foreach (Node node in targetNodes)
                {
                    SetBoneWeight(node, boneWeight);
                }
            }
        }
        void DoVerticesInspector()
        {
            if (spriteMeshCache.selection.Count > 0)
            {
                string[] names = spriteMeshCache.GetBoneNames("Unassigned");

                BoneWeight boneWeight = BoneWeight.Create();

                EditorGUI.BeginChangeCheck();

                bool mixedBoneIndex0 = false;
                bool mixedBoneIndex1 = false;
                bool mixedBoneIndex2 = false;
                bool mixedBoneIndex3 = false;
                bool changedIndex0   = false;
                bool changedIndex1   = false;
                bool changedIndex2   = false;
                bool changedIndex3   = false;
                bool mixedWeight     = false;

                if (spriteMeshCache.multiselection)
                {
                    mixedWeight = true;

                    int boneIndex = -1;
                    mixedBoneIndex0 = IsMixedBoneIndex(0, out boneIndex);
                    if (!mixedBoneIndex0)
                    {
                        boneWeight.boneIndex0 = boneIndex;
                    }
                    mixedBoneIndex1 = IsMixedBoneIndex(1, out boneIndex);
                    if (!mixedBoneIndex1)
                    {
                        boneWeight.boneIndex1 = boneIndex;
                    }
                    mixedBoneIndex2 = IsMixedBoneIndex(2, out boneIndex);
                    if (!mixedBoneIndex2)
                    {
                        boneWeight.boneIndex2 = boneIndex;
                    }
                    mixedBoneIndex3 = IsMixedBoneIndex(3, out boneIndex);
                    if (!mixedBoneIndex3)
                    {
                        boneWeight.boneIndex3 = boneIndex;
                    }
                }
                else
                {
                    boneWeight = spriteMeshCache.GetBoneWeight(spriteMeshCache.selectedNode);
                }

                EditorGUI.BeginChangeCheck();

                EditorGUI.BeginChangeCheck();
                boneWeight    = EditorGUIExtra.Weight(boneWeight, 0, names, mixedBoneIndex0, mixedWeight);
                changedIndex0 = EditorGUI.EndChangeCheck();

                EditorGUI.BeginChangeCheck();
                boneWeight    = EditorGUIExtra.Weight(boneWeight, 1, names, mixedBoneIndex1, mixedWeight);
                changedIndex1 = EditorGUI.EndChangeCheck();

                EditorGUI.BeginChangeCheck();
                boneWeight    = EditorGUIExtra.Weight(boneWeight, 2, names, mixedBoneIndex2, mixedWeight);
                changedIndex2 = EditorGUI.EndChangeCheck();

                EditorGUI.BeginChangeCheck();
                boneWeight    = EditorGUIExtra.Weight(boneWeight, 3, names, mixedBoneIndex3, mixedWeight);
                changedIndex3 = EditorGUI.EndChangeCheck();

                if (EditorGUI.EndChangeCheck())
                {
                    spriteMeshCache.RegisterUndo("modify weights");

                    if (spriteMeshCache.multiselection)
                    {
                        List <Node> selectedNodes = spriteMeshCache.selectedNodes;

                        foreach (Node node in selectedNodes)
                        {
                            BoneWeight l_boneWeight = spriteMeshCache.GetBoneWeight(node);

                            if (!mixedBoneIndex0 || changedIndex0)
                            {
                                l_boneWeight.SetWeight(0, boneWeight.boneIndex0, l_boneWeight.weight0);
                            }
                            if (!mixedBoneIndex1 || changedIndex1)
                            {
                                l_boneWeight.SetWeight(1, boneWeight.boneIndex1, l_boneWeight.weight1);
                            }
                            if (!mixedBoneIndex2 || changedIndex2)
                            {
                                l_boneWeight.SetWeight(2, boneWeight.boneIndex2, l_boneWeight.weight2);
                            }
                            if (!mixedBoneIndex3 || changedIndex3)
                            {
                                l_boneWeight.SetWeight(3, boneWeight.boneIndex3, l_boneWeight.weight3);
                            }

                            spriteMeshCache.SetBoneWeight(node, l_boneWeight);
                        }
                    }
                    else
                    {
                        spriteMeshCache.SetBoneWeight(spriteMeshCache.selectedNode, boneWeight);
                    }
                }

                EditorGUI.showMixedValue = false;
            }
        }
Ejemplo n.º 4
0
 public void SetBoneWeight(Node node, BoneWeight boneWeight)
 {
     boneWeights[node.index] = boneWeight;
     isDirty = true;
 }
Ejemplo n.º 5
0
        public void SmoothWeights(List <Node> targetNodes)
        {
            float[,] weights = new float[nodes.Count, bindPoses.Count];
            Array.Clear(weights, 0, weights.Length);

            List <int> usedIndices = new List <int>();

            for (int i = 0; i < nodes.Count; i++)
            {
                usedIndices.Clear();

                BoneWeight weight = boneWeights[i];

                if (weight.boneIndex0 >= 0)
                {
                    weights[i, weight.boneIndex0] = weight.weight0;
                    usedIndices.Add(weight.boneIndex0);
                }
                if (weight.boneIndex1 >= 0 && !usedIndices.Contains(weight.boneIndex1))
                {
                    weights[i, weight.boneIndex1] = weight.weight1;
                    usedIndices.Add(weight.boneIndex1);
                }
                if (weight.boneIndex2 >= 0 && !usedIndices.Contains(weight.boneIndex2))
                {
                    weights[i, weight.boneIndex2] = weight.weight2;
                    usedIndices.Add(weight.boneIndex2);
                }
                if (weight.boneIndex3 >= 0 && !usedIndices.Contains(weight.boneIndex3))
                {
                    weights[i, weight.boneIndex3] = weight.weight3;
                    usedIndices.Add(weight.boneIndex3);
                }
            }

            float[] denominator = new float[nodes.Count];
            float[,] smoothedWeights = new float[nodes.Count, bindPoses.Count];
            Array.Clear(smoothedWeights, 0, smoothedWeights.Length);

            for (int i = 0; i < indices.Count / 3; ++i)
            {
                for (int j = 0; j < 3; ++j)
                {
                    int j1 = (j + 1) % 3;
                    int j2 = (j + 2) % 3;

                    for (int k = 0; k < bindPoses.Count; ++k)
                    {
                        smoothedWeights[indices[i * 3 + j], k] += weights[indices[i * 3 + j1], k] + weights[indices[i * 3 + j2], k];
                    }

                    denominator[indices[i * 3 + j]] += 2;
                }
            }

            for (int i = 0; i < nodes.Count; ++i)
            {
                for (int j = 0; j < bindPoses.Count; ++j)
                {
                    smoothedWeights[i, j] /= denominator[i];
                }
            }

            float[,] smoothedWeightsTransposed = new float[bindPoses.Count, nodes.Count];

            for (int i = 0; i < nodes.Count; ++i)
            {
                for (int j = 0; j < bindPoses.Count; ++j)
                {
                    smoothedWeightsTransposed[j, i] = smoothedWeights[i, j];
                }
            }

            FillBoneWeights(targetNodes, smoothedWeightsTransposed);

            isDirty = true;
        }
Ejemplo n.º 6
0
        BoneWeight CreateBoneWeightFromWeights(List <float> weights)
        {
            BoneWeight boneWeight = new BoneWeight();

            float weight = 0f;
            int   index  = -1;

            weight = weights.Max();
            if (weight < 0.01f)
            {
                weight = 0f;
            }
            index = weight > 0f? weights.IndexOf(weight) : -1;

            boneWeight.weight0    = weight;
            boneWeight.boneIndex0 = index;

            if (index >= 0)
            {
                weights[index] = 0f;
            }

            weight = weights.Max();
            if (weight < 0.01f)
            {
                weight = 0f;
            }
            index = weight > 0f? weights.IndexOf(weight) : -1;

            boneWeight.weight1    = weight;
            boneWeight.boneIndex1 = index;

            if (index >= 0)
            {
                weights[index] = 0f;
            }

            weight = weights.Max();
            if (weight < 0.01f)
            {
                weight = 0f;
            }
            index = weight > 0f? weights.IndexOf(weight) : -1;

            boneWeight.weight2    = weight;
            boneWeight.boneIndex2 = index;

            if (index >= 0)
            {
                weights[index] = 0f;
            }

            weight = weights.Max();
            if (weight < 0.01f)
            {
                weight = 0f;
            }
            index = weight > 0f? weights.IndexOf(weight) : -1;

            boneWeight.weight3    = weight;
            boneWeight.boneIndex3 = index;

            float sum = boneWeight.weight0 +
                        boneWeight.weight1 +
                        boneWeight.weight2 +
                        boneWeight.weight3;

            if (sum > 0f)
            {
                boneWeight.weight0 /= sum;
                boneWeight.weight1 /= sum;
                boneWeight.weight2 /= sum;
                boneWeight.weight3 /= sum;
            }

            return(boneWeight);
        }
Ejemplo n.º 7
0
        public static void UpdateAssets(SpriteMesh spriteMesh, SpriteMeshData spriteMeshData)
        {
            if (spriteMesh && spriteMeshData)
            {
                string spriteMeshPath = AssetDatabase.GetAssetPath(spriteMesh);

                SerializedObject   spriteMeshSO        = new SerializedObject(spriteMesh);
                SerializedProperty sharedMeshProp      = spriteMeshSO.FindProperty("m_SharedMesh");
                SerializedProperty sharedMaterialsProp = spriteMeshSO.FindProperty("m_SharedMaterials");

                if (!spriteMesh.sharedMesh)
                {
                    Mesh mesh = new Mesh();
                    mesh.hideFlags = HideFlags.HideInHierarchy;
                    AssetDatabase.AddObjectToAsset(mesh, spriteMeshPath);

                    spriteMeshSO.Update();
                    sharedMeshProp.objectReferenceValue = mesh;
                    spriteMeshSO.ApplyModifiedProperties();
                    EditorUtility.SetDirty(mesh);
                }

                spriteMesh.sharedMesh.name = spriteMesh.name;

                if (spriteMesh.sharedMaterials.Length == 0)
                {
                    Material material = new Material(Shader.Find("Sprites/Default"));
                    material.mainTexture = SpriteUtility.GetSpriteTexture(spriteMesh.sprite, false);

                    AssetDatabase.AddObjectToAsset(material, spriteMeshPath);

                    spriteMeshSO.Update();
                    sharedMaterialsProp.arraySize = 1;
                    sharedMaterialsProp.GetArrayElementAtIndex(0).objectReferenceValue = material;
                    spriteMeshSO.ApplyModifiedProperties();
                }

                for (int i = 0; i < spriteMesh.sharedMaterials.Length; i++)
                {
                    Material material = spriteMesh.sharedMaterials [i];

                    if (material)
                    {
                        if (spriteMesh.sprite)
                        {
                            material.mainTexture = SpriteUtility.GetSpriteTexture(spriteMesh.sprite, false);
                        }

                        material.name      = spriteMesh.name + "_" + i;
                        material.hideFlags = HideFlags.HideInHierarchy;
                        EditorUtility.SetDirty(material);
                    }
                }

                spriteMeshData.hideFlags = HideFlags.HideInHierarchy;
                EditorUtility.SetDirty(spriteMeshData);

                int width  = 0;
                int height = 0;

                GetSpriteTextureSize(spriteMesh.sprite, ref width, ref height);

                Vector3[] vertices = GetMeshVertices(spriteMesh.sprite, spriteMeshData);

                Vector2 textureWidthHeightInv = new Vector2(1f / width, 1f / height);

                Vector2[] uvs = (new List <Vector2>(spriteMeshData.vertices)).ConvertAll(v => Vector2.Scale(v, textureWidthHeightInv)).ToArray();

                Vector3[] normals = (new List <Vector3>(vertices)).ConvertAll(v => Vector3.back).ToArray();

                BoneWeight[] boneWeightsData = spriteMeshData.boneWeights;

                if (boneWeightsData.Length != spriteMeshData.vertices.Length)
                {
                    boneWeightsData = new BoneWeight[spriteMeshData.vertices.Length];
                }

                List <UnityEngine.BoneWeight> boneWeights = new List <UnityEngine.BoneWeight>(boneWeightsData.Length);

                List <float> verticesOrder = new List <float>(spriteMeshData.vertices.Length);

                for (int i = 0; i < boneWeightsData.Length; i++)
                {
                    BoneWeight boneWeight = boneWeightsData[i];

                    List <KeyValuePair <int, float> > pairs = new List <KeyValuePair <int, float> >();
                    pairs.Add(new KeyValuePair <int, float>(boneWeight.boneIndex0, boneWeight.weight0));
                    pairs.Add(new KeyValuePair <int, float>(boneWeight.boneIndex1, boneWeight.weight1));
                    pairs.Add(new KeyValuePair <int, float>(boneWeight.boneIndex2, boneWeight.weight2));
                    pairs.Add(new KeyValuePair <int, float>(boneWeight.boneIndex3, boneWeight.weight3));

                    pairs = pairs.OrderByDescending(s => s.Value).ToList();

                    UnityEngine.BoneWeight boneWeight2 = new UnityEngine.BoneWeight();
                    boneWeight2.boneIndex0 = Mathf.Max(0, pairs[0].Key);
                    boneWeight2.boneIndex1 = Mathf.Max(0, pairs[1].Key);
                    boneWeight2.boneIndex2 = Mathf.Max(0, pairs[2].Key);
                    boneWeight2.boneIndex3 = Mathf.Max(0, pairs[3].Key);
                    boneWeight2.weight0    = pairs[0].Value;
                    boneWeight2.weight1    = pairs[1].Value;
                    boneWeight2.weight2    = pairs[2].Value;
                    boneWeight2.weight3    = pairs[3].Value;

                    boneWeights.Add(boneWeight2);

                    float vertexOrder = i;

                    if (spriteMeshData.bindPoses.Length > 0)
                    {
                        vertexOrder = spriteMeshData.bindPoses[boneWeight2.boneIndex0].zOrder * boneWeight2.weight0 +
                                      spriteMeshData.bindPoses[boneWeight2.boneIndex1].zOrder * boneWeight2.weight1 +
                                      spriteMeshData.bindPoses[boneWeight2.boneIndex2].zOrder * boneWeight2.weight2 +
                                      spriteMeshData.bindPoses[boneWeight2.boneIndex3].zOrder * boneWeight2.weight3;
                    }

                    verticesOrder.Add(vertexOrder);
                }

                List <WeightedTriangle> weightedTriangles = new List <WeightedTriangle>(spriteMeshData.indices.Length / 3);

                for (int i = 0; i < spriteMeshData.indices.Length; i += 3)
                {
                    int p1 = spriteMeshData.indices[i];
                    int p2 = spriteMeshData.indices[i + 1];
                    int p3 = spriteMeshData.indices[i + 2];

                    weightedTriangles.Add(new WeightedTriangle(p1, p2, p3,
                                                               verticesOrder[p1],
                                                               verticesOrder[p2],
                                                               verticesOrder[p3]));
                }

                weightedTriangles = weightedTriangles.OrderBy(t => t.weight).ToList();

                List <int> indices = new List <int>(spriteMeshData.indices.Length);

                for (int i = 0; i < weightedTriangles.Count; ++i)
                {
                    WeightedTriangle t = weightedTriangles[i];
                    indices.Add(t.p1);
                    indices.Add(t.p2);
                    indices.Add(t.p3);
                }

                List <Matrix4x4> bindposes = (new List <BindInfo>(spriteMeshData.bindPoses)).ConvertAll(p => p.bindPose);

                for (int i = 0; i < bindposes.Count; i++)
                {
                    Matrix4x4 bindpose = bindposes [i];

                    bindpose.m23 = 0f;

                    bindposes[i] = bindpose;
                }

                spriteMesh.sharedMesh.Clear();
                spriteMesh.sharedMesh.vertices    = vertices;
                spriteMesh.sharedMesh.uv          = uvs;
                spriteMesh.sharedMesh.triangles   = indices.ToArray();
                spriteMesh.sharedMesh.normals     = normals;
                spriteMesh.sharedMesh.boneWeights = boneWeights.ToArray();
                spriteMesh.sharedMesh.bindposes   = bindposes.ToArray();
                spriteMesh.sharedMesh.RecalculateBounds();

                RebuildBlendShapes(spriteMesh);
            }
        }
Ejemplo n.º 8
0
        public static void UpdateAssets(SpriteMesh spriteMesh)
        {
            if (spriteMesh)
            {
                string spriteMeshPath = AssetDatabase.GetAssetPath(spriteMesh);

                GameObject go       = AssetDatabase.LoadAssetAtPath(spriteMeshPath, typeof(GameObject)) as GameObject;
                Mesh       mesh     = AssetDatabase.LoadAssetAtPath(spriteMeshPath, typeof(Mesh)) as Mesh;
                Material   material = AssetDatabase.LoadAssetAtPath(spriteMeshPath, typeof(Material)) as Material;

                spriteMesh.name = go.name;

                if (!mesh)
                {
                    mesh = new Mesh();
                    AssetDatabase.AddObjectToAsset(mesh, spriteMeshPath);
                }

                mesh.name = go.name;

                if (!material)
                {
                    material             = new Material(Shader.Find("Unlit/Transparent"));
                    material.mainTexture = spriteMesh.sprite.texture;
                    AssetDatabase.AddObjectToAsset(material, spriteMeshPath);
                }

                material.name = go.name;

                List <Vector3>    vertices    = new List <Vector3>(spriteMesh.texVertices.Count);
                List <Vector2>    uvs         = new List <Vector2>(spriteMesh.texVertices.Count);
                List <Vector3>    normals     = new List <Vector3>(spriteMesh.texVertices.Count);
                List <BoneWeight> boneWeights = new List <BoneWeight>(spriteMesh.texVertices.Count);

                for (int i = 0; i < spriteMesh.texVertices.Count; i++)
                {
                    Vertex vertex = spriteMesh.texVertices[i];
                    vertices.Add(TexCoordToVertex(spriteMesh, vertex.vertex));
                    uvs.Add(new Vector2(vertex.vertex.x / spriteMesh.sprite.texture.width,
                                        vertex.vertex.y / spriteMesh.sprite.texture.height));
                    normals.Add(Vector3.back);

                    List <KeyValuePair <int, float> > pairs = new List <KeyValuePair <int, float> >();
                    pairs.Add(new KeyValuePair <int, float>(vertex.boneWeight.boneIndex0, vertex.boneWeight.weight0));
                    pairs.Add(new KeyValuePair <int, float>(vertex.boneWeight.boneIndex1, vertex.boneWeight.weight1));
                    pairs.Add(new KeyValuePair <int, float>(vertex.boneWeight.boneIndex2, vertex.boneWeight.weight2));
                    pairs.Add(new KeyValuePair <int, float>(vertex.boneWeight.boneIndex3, vertex.boneWeight.weight3));

                    pairs = pairs.OrderByDescending(s => s.Value).ToList();

                    BoneWeight boneWeight = new BoneWeight();
                    boneWeight.boneIndex0 = pairs[0].Key;
                    boneWeight.boneIndex1 = pairs[1].Key;
                    boneWeight.boneIndex2 = pairs[2].Key;
                    boneWeight.boneIndex3 = pairs[3].Key;
                    boneWeight.weight0    = pairs[0].Value;
                    boneWeight.weight1    = pairs[1].Value;
                    boneWeight.weight2    = pairs[2].Value;
                    boneWeight.weight3    = pairs[3].Value;
                    boneWeights.Add(boneWeight);
                }

                mesh.Clear();
                mesh.vertices    = vertices.ToArray();
                mesh.uv          = uvs.ToArray();
                mesh.triangles   = spriteMesh.indices.ToArray();
                mesh.normals     = normals.ToArray();
                mesh.boneWeights = boneWeights.ToArray();
                mesh.bindposes   = spriteMesh.bindPoses.ConvertAll(bindPose => bindPose.bindPose).ToArray();
                mesh.RecalculateBounds();
            }
        }