Пример #1
0
    // Start is called before the first frame update
    void Start()
    {
        addPointButton.onClick.AddListener(SetAddPointState);

        themesh      = GetComponent <MeshFilter>().sharedMesh;
        triangles    = themesh.triangles;
        meshvertices = themesh.vertices;

        arapTris     = new ARAPTriangle[triangles.Length / 3];
        reorderVerID = new int[meshvertices.Length];
        mvConstraint = new List <int>();
        mvDeformed   = meshvertices;

        ///precompute variables
        for (int i = 0; i < triangles.Length / 3; i++)
        {
            ARAPTriangle t  = new ARAPTriangle();
            Vector3      v0 = meshvertices[triangles[i * 3]];
            Vector3      v1 = meshvertices[triangles[i * 3 + 1]];
            Vector3      v2 = meshvertices[triangles[i * 3 + 2]];

            var v2local = ARAPOperation.FindLocalCoordinator(v0, v1, v2);
            var v0local = ARAPOperation.FindLocalCoordinator(v1, v2, v0);
            var v1local = ARAPOperation.FindLocalCoordinator(v2, v0, v1);

            t.SetLocalXY(v0local, v1local, v2local);
            t.SetVertexID(triangles[i * 3], triangles[i * 3 + 1], triangles[i * 3 + 2]);

            t.scale_factor_divisor = Vector3.Dot(v1 - v0, v1 - v0);
            t.PreComputeScaleAdjustmentMatrixFC();

            arapTris[i] = t;
        }

        drawTris = new List <Vector3>();
        for (int i = 0; i < triangles.Length / 3; i++)
        {
            drawTris.Add(mvDeformed[triangles[i * 3]]);
            drawTris.Add(mvDeformed[triangles[i * 3 + 1]]);
            drawTris.Add(mvDeformed[triangles[i * 3 + 2]]);
        }
    }
Пример #2
0
    public static Vector3[] AdjustScaleToTriangle(ARAPTriangle thetriangle, Vector3[] mDrformedVertex)
    {
        Matrix triangle_points_coords = Matrix.ZeroMatrix(6, 1);

        for (int i = 0; i < 3; i++)
        {
            int vid = thetriangle.vertex_id[i];
            triangle_points_coords[i * 2, 0]     = mDrformedVertex[vid].x;
            triangle_points_coords[i * 2 + 1, 0] = mDrformedVertex[vid].y;
        }

        Matrix theF = thetriangle.mF;
        Matrix theC = thetriangle.mC;

        Matrix  vfittedcoords = -1 * theF * theC * triangle_points_coords;
        Vector3 v0f           = new Vector3((float)vfittedcoords[0, 0], (float)vfittedcoords[1, 0], 0);
        Vector3 v1f           = new Vector3((float)vfittedcoords[2, 0], (float)vfittedcoords[3, 0], 0);

        float x01 = thetriangle.local_xy[2].x;
        float y01 = thetriangle.local_xy[2].y;

        Vector3 v01    = v1f - v0f;
        Vector3 v01R90 = Quaternion.AngleAxis(90, Vector3.forward) * (v01);
        Vector3 v2f    = v0f + x01 * (v01) + y01 * v01R90;

        Vector3[] updateTriPoints = new Vector3[3];
        updateTriPoints[0] = v0f; updateTriPoints[1] = v1f; updateTriPoints[2] = v2f;

        Vector3 centermass = (v0f + v1f + v2f) / 3;
        float   sf         = Mathf.Sqrt(thetriangle.scale_factor_divisor / Vector3.Dot(v01, v01));

        for (int i = 0; i < 3; i++)
        {
            updateTriPoints[i] -= centermass;
            updateTriPoints[i] *= sf;
            updateTriPoints[i] += centermass;
        }
        return(updateTriPoints);
    }
Пример #3
0
    void MeshDeform()
    {
        int nConstaint = mvConstraint.Count;

        if (mvConstraint.Count > 1)
        {
            Matrix vq = new Matrix(2 * nConstaint, 1);
            for (int i = 0; i < nConstaint; i++)
            {
                vq[2 * i, 0]     = mvDeformed[mvConstraint[i]].x;
                vq[2 * i + 1, 0] = mvDeformed[mvConstraint[i]].y;
            }
            //step1 deform
            var vu     = scaleFreeMatrix * vq;
            int nVerts = meshvertices.Length;

            for (int i = 0; i < nVerts; i++)
            {
                if (mvConstraint.IndexOf(i) != -1)
                {
                    continue;
                }
                int    nRow = reorderVerID[i];
                double fx   = vu[2 * nRow, 0];
                double fy   = vu[2 * nRow + 1, 0];
                mvDeformed[i] = new Vector3((float)fx, (float)fy, 0);
            }
            //step 2.1
            float[] f = new float[2 * meshvertices.Length];
            for (int i = 0; i < triangles.Length / 3; i++)
            {
                ARAPTriangle thetri      = arapTris[i];
                Vector3[]    updatedTris = ARAPOperation.AdjustScaleToTriangle(thetri, mvDeformed);

                for (int j = 0; j < 3; j++)
                {
                    var v0f = updatedTris[j];
                    var v1f = updatedTris[(j + 1) % 3];

                    int v0f_id = reorderVerID[thetri.vertex_id[j]];
                    int v1f_id = reorderVerID[thetri.vertex_id[(j + 1) % 3]];

                    f[2 * v0f_id]     += -2 * v0f.x + 2 * v1f.x;
                    f[2 * v0f_id + 1] += -2 * v0f.y + 2 * v1f.y;
                    f[2 * v1f_id]     += 2 * v0f.x - 2 * v1f.x;
                    f[2 * v1f_id + 1] += 2 * v0f.y - 2 * v1f.y;
                }
            }
            //step2.2
            int nFreeVerts = nVerts - nConstaint;
            Debug.Log(f[2 * nFreeVerts - 1]);
            Debug.Log(f[2 * nFreeVerts]);
            Matrix f0 = Matrix.ZeroMatrix(2 * nFreeVerts, 1);
            for (int i = 0; i < 2 * nFreeVerts; i++)
            {
                f0[i, 0] = f[i];
            }
            for (int i = 0; i < nConstaint; i++)
            {
                vq[2 * i, 0]     = mvDeformed[mvConstraint[i]].x;
                vq[2 * i + 1, 0] = mvDeformed[mvConstraint[i]].y;
            }
            Matrix mb = -1 * (mHandmD[1] * vq + f0);
            Matrix mu = mHandmD[0].SolveWith(mb);

            for (int i = 0; i < nVerts; i++)
            {
                if (mvConstraint.IndexOf(i) != -1)
                {
                    continue;
                }
                int    nRow = reorderVerID[i];
                double fx   = mu[2 * nRow, 0];
                double fy   = mu[2 * nRow + 1, 0];
                mvDeformed[i] = new Vector3((float)fx, (float)fy, 0);
            }

            drawTris = new List <Vector3>();
            for (int i = 0; i < triangles.Length / 3; i++)
            {
                drawTris.Add(mvDeformed[triangles[i * 3]]);
                drawTris.Add(mvDeformed[triangles[i * 3 + 1]]);
                drawTris.Add(mvDeformed[triangles[i * 3 + 2]]);
            }
        }
    }
Пример #4
0
    //call every time add constraint point
    public static Matrix UpdateConstraint(int ninitialVer, int nContraint, int[] mVertexMap, ARAPTriangle[] triangles)
    {
        Matrix mFirstMatrix = Matrix.ZeroMatrix(1, 1);
        //matrix computation
        int nfreeVec = ninitialVer - nContraint;

        if (nContraint > 1)
        {
            Matrix mG = Matrix.ZeroMatrix(2 * ninitialVer, 2 * ninitialVer);
            for (int i = 0; i < triangles.Length; i++)
            {
                ARAPTriangle tris = triangles[i];
                for (int j = 0; j < 3; j++)
                {
                    int v0_id = mVertexMap[tris.vertex_id[j]];
                    int v1_id = mVertexMap[tris.vertex_id[(j + 1) % 3]];
                    int v2_id = mVertexMap[tris.vertex_id[(j + 2) % 3]];

                    float x01 = tris.local_xy[(j + 2) % 3].x;
                    float y01 = tris.local_xy[(j + 2) % 3].y;

                    mG[2 * v0_id, 2 * v0_id] += Mathf.Pow(x01, 2) - 2 * x01 + Mathf.Pow(y01, 2) + 1;

                    mG[2 * v0_id, 2 * v0_id + 1]  = 0 / 2;
                    mG[2 * v0_id + 1, 2 * v0_id] += 0;

                    mG[2 * v0_id, 2 * v1_id] += (1 - x01) * x01 - Mathf.Pow(y01, 2);
                    mG[2 * v1_id, 2 * v0_id] += (1 - x01) * x01 - Mathf.Pow(y01, 2);


                    mG[2 * v0_id, 2 * v1_id + 1] += -y01;
                    mG[2 * v1_id + 1, 2 * v0_id] += -y01;

                    mG[2 * v0_id, 2 * v2_id] += -(1 - x01);
                    mG[2 * v2_id, 2 * v0_id] += -(1 - x01);

                    mG[2 * v0_id, 2 * v2_id + 1] += y01;
                    mG[2 * v2_id + 1, 2 * v0_id] += y01;

                    mG[2 * v0_id + 1, 2 * v0_id + 1] += Mathf.Pow(x01, 2) - 2 * x01 + Mathf.Pow(y01, 2) + 1;

                    mG[2 * v0_id + 1, 2 * v1_id] += y01;
                    mG[2 * v1_id, 2 * v0_id + 1] += y01;

                    mG[2 * v0_id + 1, 2 * v1_id + 1] += x01 - x01 * x01 - y01 * y01;
                    mG[2 * v1_id + 1, 2 * v0_id + 1] += x01 - x01 * x01 - y01 * y01;

                    mG[2 * v0_id + 1, 2 * v2_id] += -y01;
                    mG[2 * v2_id, 2 * v0_id + 1] += -y01;

                    mG[2 * v0_id + 1, 2 * v2_id + 1] += -1 + x01;
                    mG[2 * v2_id + 1, 2 * v0_id + 1] += -1 + x01;

                    mG[2 * v1_id, 2 * v1_id] += Mathf.Pow(x01, 2) + Mathf.Pow(y01, 2);

                    mG[2 * v1_id, 2 * v1_id + 1] += 0 / 2;
                    mG[2 * v1_id + 1, 2 * v1_id] += 0 / 2;

                    mG[2 * v1_id, 2 * v2_id] += -x01;
                    mG[2 * v2_id, 2 * v1_id] += -x01;

                    mG[2 * v1_id, 2 * v2_id + 1] += -y01;
                    mG[2 * v2_id + 1, 2 * v1_id] += -y01;

                    mG[2 * v1_id + 1, 2 * v1_id + 1] += Mathf.Pow(x01, 2) + Mathf.Pow(y01, 2);

                    mG[2 * v1_id + 1, 2 * v2_id] += y01;
                    mG[2 * v2_id, 2 * v1_id + 1] += y01;

                    mG[2 * v1_id + 1, 2 * v2_id + 1] += -x01;
                    mG[2 * v2_id + 1, 2 * v1_id + 1] += -x01;


                    mG[2 * v2_id, 2 * v2_id] += 1;

                    mG[2 * v2_id, 2 * v2_id + 1] += 0;
                    mG[2 * v2_id + 1, 2 * v2_id] += 0;

                    mG[2 * v2_id + 1, 2 * v2_id + 1] += 1;
                }
            }
            Matrix mG00 = mG.SubMatrix(0, 0, 2 * nfreeVec, 2 * nfreeVec);
            Matrix mG01 = mG.SubMatrix(0, 2 * nfreeVec, 2 * nfreeVec, 2 * nContraint);
            Matrix mG10 = mG.SubMatrix(2 * nfreeVec, 0, 2 * nContraint, 2 * nfreeVec);

            Matrix mGprime = mG00 + Matrix.Transpose(mG00);
            Matrix mB      = mG01 + Matrix.Transpose(mG10);

            Matrix mGprimeInverse = mGprime.Invert();

            mFirstMatrix = -1 * mGprimeInverse * mB;
        }
        return(mFirstMatrix);
    }