// Update is called once per frame void Update() { if (Input.GetMouseButton(0)) { if (!isAddpoint)//move constraint point { int selected_id = FindHitVertex(Input.mousePosition); if (selected_id != -1 && mvConstraint.IndexOf(selected_id) != -1) { var newpos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 20)); mvDeformed[selected_id] = newpos; MeshDeform(); } } else //add constraint point { if (Input.GetMouseButtonDown(0)) { int selectedn = FindHitVertex(Input.mousePosition); if (selectedn != -1) { if (mvConstraint.IndexOf(selectedn) == -1) { FindIsinConstraint(selectedn); ReorderVertex(); scaleFreeMatrix = ARAPOperation.UpdateConstraint(meshvertices.Length, mvConstraint.Count, reorderVerID, arapTris); mHandmD = ARAPOperation.PrecomputeFittingMatrix(meshvertices.Length, mvConstraint.Count, arapTris, reorderVerID); } } } } } themesh.vertices = mvDeformed; }
// 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]]); } }
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]]); } } }