Example #1
0
        public static int[] ComputeLinearlyIndependentBlendShapeIndices(UnityEngine.Mesh mesh, int[] blendShapeIndices)
        {
            var numShapes = blendShapeIndices.Length;
            var outShapes = new int[numShapes];

            var numVertices  = mesh.vertexCount;
            var numEquations = 3 * numVertices;
            var numVariables = 0;

            var tmpPositions = new UnityEngine.Vector3[numVertices];
            var tmpTangents  = new UnityEngine.Vector3[numVertices];
            var tmpNormals   = new UnityEngine.Vector3[numVertices];

            var A = new double[numEquations, 1];            // start with an empty column
            var _ = new double[numEquations];

            {
                for (int j = 0; j != numShapes; j++)
                {
                    int k = blendShapeIndices[j];

                    if (EditorUtilityProxy.DisplayCancelableProgressBar("Filter linearly independent blend shapes", "Processing shape " + k + " (" + mesh.GetBlendShapeName(k) + ")", j / (float)numShapes))
                    {
                        outShapes = null;
                        break;                        // user cancelled
                    }
                    mesh.GetBlendShapeFrameVertices(k, 0, tmpPositions, tmpNormals, tmpTangents);

                    for (int i = 0; i != numVertices; i++)
                    {
                        _[i * 3 + 0] = tmpPositions[i].x;
                        _[i * 3 + 1] = tmpPositions[i].y;
                        _[i * 3 + 2] = tmpPositions[i].z;
                    }

                    A.SetColumn(numVariables, _);                    // write to empty column

                    var rank = Matrix.Rank(A.TransposeAndDot(A));
                    if (rank == numVariables + 1)
                    {
                        outShapes[numVariables++] = k;
                        A = A.Concatenate(_);                        // grow by one column
                    }
                    else
                    {
                        UnityEngine.Debug.LogWarning("shape " + k + " (" + mesh.GetBlendShapeName(k) + ") did NOT increase rank => skip");
                    }
                }

                EditorUtilityProxy.ClearProgressBar();
            }

            if (outShapes != null)
            {
                Array.Resize(ref outShapes, numVariables);
            }

            return(outShapes);
        }