void Update() { //Physics Verlet.Integrate(clothVerts, prevClothVerts, scaledGravity, Time.deltaTime, previousDeltaTime); previousDeltaTime = Time.deltaTime; //Anchor the Top Corner of the Cloth clothVerts[0] = prevClothVerts[0] = anchor1.position; clothVerts[10] = prevClothVerts[10] = anchor2.position; //Constraint Resolution Verlet.resolveDistanceConstraints(constraints, ref clothVerts, ref accumulatedDisplacements, 1); //Graphics clothMesh.vertices = clothVerts; clothMesh.RecalculateNormals(); clothMesh.RecalculateBounds(); clothMesh.UploadMeshData(false); }
void Update() { //Translate the points into world space for (int i = 0; i < bodyVerts.Length; i++) { bodyVerts[i] = transform.TransformPoint(bodyVerts[i]); } //Physics float currentDeltaTime = Mathf.Clamp(Time.deltaTime, 0.01f, previousDeltaTime * 1.4f); Verlet.Integrate(bodyVerts, prevBodyVerts, scaledGravity, currentDeltaTime, previousDeltaTime); previousDeltaTime = currentDeltaTime; //Anchor a point on the body if (anchor != null && anchor.gameObject.activeInHierarchy) { bodyVerts[0] = prevBodyVerts[0] = anchor.position; } //Also sneak in a ground plane here: Vector3 groundPlanePos = groundPlane.position; Vector3 groundPlaneNormal = -groundPlane.forward; for (int j = 0; j < bodyVerts.Length; j++) { if (Vector3.Dot(bodyVerts[j] - groundPlanePos, groundPlaneNormal) < 0f) { bodyVerts[j] = Vector3.ProjectOnPlane(bodyVerts[j] - groundPlanePos, groundPlaneNormal) + groundPlanePos; bodyVerts[j] -= Vector3.ProjectOnPlane(bodyVerts[j] - prevBodyVerts[j], groundPlaneNormal) * 0.3f; } } //Calculate the the position and rotation of the body for (int i = 0; i < bodyVerts.Length; i++) { kabschVerts[i] = new Vector4(bodyVerts[i].x, bodyVerts[i].y, bodyVerts[i].z, 1f); } ; kabschVerts.CopyTo(kabschVertsArray); Matrix4x4 toWorldSpace = kabschSolver.SolveKabsch(originalVerts, kabschVertsArray, true); constrainVertsToDeformation(originalVerts, toWorldSpace, ref bodyVerts); Verlet.RecalculateNormalsNonAlloc(bodyVerts, bodyTriangles, ref bodyNormals); //Move the points into local space for rendering transform.position = toWorldSpace.GetVector3(); transform.rotation = toWorldSpace.GetQuaternion(); for (int i = 0; i < bodyVerts.Length; i++) { bodyVerts[i] = transform.InverseTransformPoint(bodyVerts[i]); renderNormals[i] = transform.InverseTransformDirection(bodyNormals[i]); } Debug.DrawRay(transform.position, toWorldSpace * (Vector3.Cross(yBasis, zBasis).normalized *xScale), Color.red); Debug.DrawRay(transform.position, toWorldSpace * yBasis, Color.green); Debug.DrawRay(transform.position, toWorldSpace * zBasis, Color.blue); //Graphics bodyVerts.CopyTo(bodyVertsArray); renderNormals.CopyTo(renderNormalsArray); bodyMesh.vertices = bodyVertsArray; bodyMesh.normals = renderNormalsArray; bodyMesh.RecalculateBounds(); bodyMesh.UploadMeshData(false); }
void Update() { //Translate the points into world space for (int i = 0; i < bodyVerts.Length; i++) { bodyVerts[i] = transform.TransformPoint(bodyVerts[i]); } //Physics float currentDeltaTime = Mathf.Clamp(Time.deltaTime, 0.01f, previousDeltaTime * 1.4f); Verlet.Integrate(bodyVerts, prevBodyVerts, scaledGravity, currentDeltaTime, previousDeltaTime); previousDeltaTime = currentDeltaTime; //Anchor a point on the body if (anchor != null && anchor.gameObject.activeInHierarchy) { bodyVerts[0] = prevBodyVerts[0] = anchor.position; } for (int i = 0; i < solverIterations; i++) { //First, ensure that the surface area is what we think it is Verlet.resolveDistanceConstraints(constraints, ref bodyVerts, ref accumulatedDisplacements, 1); //Next, set the volume of the soft body Verlet.setVolume(inflationAmount * initialVolume, bodyVerts, bodyNormals, bodyTriangles, initialSurfaceArea, true, fastButGarbage); } //Also sneak in a ground plane here: Vector3 groundPlanePos = groundPlane.position; Vector3 groundPlaneNormal = -groundPlane.forward; for (int j = 0; j < bodyVerts.Length; j++) { if (Vector3.Dot(bodyVerts[j] - groundPlanePos, groundPlaneNormal) < 0f) { bodyVerts[j] = Vector3.ProjectOnPlane(bodyVerts[j] - groundPlanePos, groundPlaneNormal) + groundPlanePos; bodyVerts[j] -= Vector3.ProjectOnPlane(bodyVerts[j] - prevBodyVerts[j], groundPlaneNormal) * 0.3f; } } //Calculate the the position and rotation of the body for (int i = 0; i < bodyVerts.Length; i++) { kabschVerts[i] = new Vector4(bodyVerts[i].x, bodyVerts[i].y, bodyVerts[i].z, 1f); } ; Matrix4x4 toWorldSpace = kabschSolver.SolveKabsch(originalVerts, kabschVerts, transformFollowsRotation); transform.position = toWorldSpace.GetVector3(); transform.rotation = toWorldSpace.GetQuaternion(); //Move the points into local space for rendering for (int i = 0; i < bodyVerts.Length; i++) { bodyVerts[i] = transform.InverseTransformPoint(bodyVerts[i]); renderNormals[i] = transform.InverseTransformDirection(bodyNormals[i]); } //Graphics bodyMesh.vertices = bodyVerts; bodyMesh.normals = renderNormals; bodyMesh.RecalculateBounds(); bodyMesh.UploadMeshData(false); }