void Start() { //Initialize mesh and state variables MeshFilter filter = GetComponent <MeshFilter>(); bodyMesh = Instantiate(filter.mesh); bodyMesh.MarkDynamic(); bodyVerts = bodyMesh.vertices; kabschVerts = Array.ConvertAll(bodyVerts, (p => new Vector4(p.x, p.y, p.z, 1f))); originalVerts = bodyMesh.vertices; bodyTriangles = bodyMesh.triangles; bodyNormals = bodyMesh.normals; renderNormals = bodyMesh.normals; prevBodyVerts = new Vector3[bodyVerts.Length]; accumulatedDisplacements = new Vector4[bodyVerts.Length]; for (int i = 0; i < bodyVerts.Length; i++) { prevBodyVerts[i] = transform.TransformPoint(bodyVerts[i]); } filter.mesh = bodyMesh; //Create Distance Constraints from Triangles in Mesh constraints = new List <Verlet.DistConstraint>(bodyVerts.Length * 3); Verlet.setUpConstraints(bodyMesh, constraints, false); //Scale gravity by the size of this Mesh Renderer scaledGravity = new Vector3(Physics.gravity.x / transform.lossyScale.x, Physics.gravity.y / transform.lossyScale.y, Physics.gravity.z / transform.lossyScale.z); initialVolume = Verlet.VolumeOfMesh(bodyVerts, bodyTriangles); }
public SoftbodyData(Mesh bodyMesh, Transform transform, List <Verlet.DistConstraint> constraintsList, Vector3 scaledGravity, Transform ground) { bodyVerts = new NativeArray <Vector3>(bodyMesh.vertices, Allocator.Persistent); kabschVerts = new NativeArray <Vector4>(Array.ConvertAll(bodyVerts.ToArray(), (p => new Vector4(p.x, p.y, p.z, 1f))), Allocator.Persistent); int[] triangles = bodyMesh.triangles; Vector3Int[] tris = new Vector3Int[triangles.Length / 3]; for (int i = 0; i < tris.Length; i++) { tris[i] = new Vector3Int(triangles[i * 3], triangles[(i * 3) + 1], triangles[(i * 3) + 2]); } bodyTriangles = new NativeArray <Vector3Int>(tris, Allocator.Persistent); bodyNormals = new NativeArray <Vector3>(bodyMesh.normals, Allocator.Persistent); renderNormals = new NativeArray <Vector3>(bodyMesh.normals, Allocator.Persistent); prevBodyVerts = new NativeArray <Vector3>(new Vector3[bodyVerts.Length], Allocator.Persistent); accumulatedDisplacements = new NativeArray <Vector4>(new Vector4[bodyVerts.Length], Allocator.Persistent); for (int i = 0; i < bodyVerts.Length; i++) { prevBodyVerts[i] = transform.TransformPoint(bodyVerts[i]); } constraintsArray = new NativeArray <Verlet.DistConstraint>(constraintsList.ToArray(), Allocator.Persistent); dilationDistance = new NativeArray <float>(new float[1], Allocator.Persistent); initialVolume = Verlet.VolumeOfMesh(bodyVerts, bodyTriangles); initialSurfaceArea = 4f * 3.14159f; previousDeltaTime = 1f; dilationDistance[0] = 0f; this.scaledGravity = scaledGravity; localToWorld = transform.localToWorldMatrix; worldToLocal = transform.worldToLocalMatrix; groundPlanePos = ground.position; groundPlaneNormal = -ground.forward; }
void Update() { //Translate the points into world space for (int i = 0; i < bodyVerts.Length; i++) { bodyVerts[i] = transform.TransformPoint(bodyVerts[i]); } 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 clamp to the intersection of capsules for shits for (int j = 0; j < bodyVerts.Length; j++) { Vector3 capOne = Constraints.ConstrainToCapsule(bodyVerts[j], Vector3.zero, Vector3.up, 0.25f) - bodyVerts[j]; Vector3 capTwo = Constraints.ConstrainToCapsule(bodyVerts[j], Vector3.zero, Vector3.right * 1.15f, 0.25f) - bodyVerts[j]; if (capOne.sqrMagnitude < capTwo.sqrMagnitude) { bodyVerts[j] += capOne; } else { bodyVerts[j] += capTwo; } } //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, Array.ConvertAll(bodyVerts, (p => (Vector4)p))); 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]); } Debug.Log(Verlet.VolumeOfMesh(bodyVerts, bodyTriangles)); //Graphics bodyMesh.vertices = bodyVerts; bodyMesh.normals = renderNormals; bodyMesh.RecalculateBounds(); bodyMesh.UploadMeshData(false); }
void Start() { //Initialize mesh and state variables MeshFilter filter = GetComponent <MeshFilter>(); bodyMesh = Instantiate(filter.mesh); bodyMesh.MarkDynamic(); bodyVerts = new NativeArray <Vector3>(bodyMesh.vertices, Allocator.Persistent); kabschVerts = new NativeArray <Vector4>(Array.ConvertAll(bodyVerts.ToArray(), (p => new Vector4(p.x, p.y, p.z, 1f))), Allocator.Persistent); originalVerts = bodyMesh.vertices; int[] triangles = bodyMesh.triangles; Vector3Int[] tris = new Vector3Int[triangles.Length / 3]; for (int i = 0; i < tris.Length; i++) { tris[i] = new Vector3Int(triangles[i * 3], triangles[(i * 3) + 1], triangles[(i * 3) + 2]); } bodyTriangles = new NativeArray <Vector3Int>(tris, Allocator.Persistent); bodyNormals = new NativeArray <Vector3>(bodyMesh.normals, Allocator.Persistent); renderNormals = new NativeArray <Vector3>(bodyMesh.normals, Allocator.Persistent); prevBodyVerts = new NativeArray <Vector3>(new Vector3[bodyVerts.Length], Allocator.Persistent); accumulatedDisplacements = new NativeArray <Vector4>(new Vector4[bodyVerts.Length], Allocator.Persistent); for (int i = 0; i < bodyVerts.Length; i++) { prevBodyVerts[i] = transform.TransformPoint(bodyVerts[i]); } filter.mesh = bodyMesh; renderNormalsArray = new Vector3[renderNormals.Length]; bodyVertsArray = new Vector3[bodyVerts.Length]; kabschVertsArray = new Vector4[kabschVerts.Length]; //Create Distance Constraints from Triangles in Mesh constraintsList = new List <Verlet.DistConstraint>(bodyVerts.Length * 3); Verlet.setUpConstraints(bodyMesh, constraintsList, false); constraintsArray = new NativeArray <Verlet.DistConstraint>(constraintsList.ToArray(), Allocator.Persistent); //Scale gravity by the size of this Mesh Renderer scaledGravity = new Vector3(Physics.gravity.x / transform.lossyScale.x, Physics.gravity.y / transform.lossyScale.y, Physics.gravity.z / transform.lossyScale.z); initialVolume = Verlet.VolumeOfMesh(bodyVerts, bodyTriangles); optimizer.CalculateErrorDerivative = CalculateErrorDerivative; optimizer.Add(1f, "xScale"); optimizer.Add(Vector3.up, "yBasis"); optimizer.Add(Vector3.forward, "zBasis"); }
void Start() { //Initialize mesh and state variables MeshFilter filter = GetComponent <MeshFilter>(); bodyMesh = Instantiate(filter.mesh); bodyMesh.MarkDynamic(); bodyVerts = bodyMesh.vertices; originalVerts = bodyMesh.vertices; bodyTriangles = bodyMesh.triangles; bodyNormals = bodyMesh.normals; renderNormals = bodyMesh.normals; accumulatedDisplacements = new Vector4[bodyVerts.Length]; filter.mesh = bodyMesh; //Create Distance Constraints from Triangles in Mesh constraints = new List <Verlet.DistConstraint>(bodyVerts.Length * 3); Verlet.setUpConstraints(bodyMesh, constraints, false); initialVolume = Verlet.VolumeOfMesh(bodyVerts, bodyTriangles); }
public SoftbodyData(Mesh bodyMesh, Transform transform, List <Verlet.DistConstraint> constraintsList, Vector3 scaledGravity, Transform ground, float radius = 1f, float friction = 0.3f) { bodyVerts = new NativeArray <Vector3>(bodyMesh.vertices, Allocator.Persistent); for (int i = 0; i < bodyVerts.Length; i++) { bodyVerts[i] *= radius; } preCollisionVerts = new NativeArray <Vector3>(bodyVerts, Allocator.Persistent); kabschVerts = new NativeArray <Vector4>(Array.ConvertAll(bodyVerts.ToArray(), (p => new Vector4(p.x, p.y, p.z, 1f))), Allocator.Persistent); int[] triangles = bodyMesh.triangles; Vector3Int[] tris = new Vector3Int[triangles.Length / 3]; for (int i = 0; i < tris.Length; i++) { tris[i] = new Vector3Int(triangles[i * 3], triangles[(i * 3) + 1], triangles[(i * 3) + 2]); } bodyTriangles = new NativeArray <Vector3Int>(tris, Allocator.Persistent); bodyNormals = new NativeArray <Vector3>(bodyMesh.normals, Allocator.Persistent); renderNormals = new NativeArray <Vector3>(bodyMesh.normals, Allocator.Persistent); prevBodyVerts = new NativeArray <Vector3>(new Vector3[bodyVerts.Length], Allocator.Persistent); accumulatedDisplacements = new NativeArray <Vector4>(new Vector4[bodyVerts.Length], Allocator.Persistent); for (int i = 0; i < bodyVerts.Length; i++) { prevBodyVerts[i] = transform.TransformPoint(bodyVerts[i]); } raycasts = new NativeArray <RaycastCommand>(new RaycastCommand[bodyVerts.Length], Allocator.Persistent); raycastHits = new NativeArray <RaycastHit>(new RaycastHit[bodyVerts.Length], Allocator.Persistent); constraintsArray = new NativeArray <Verlet.DistConstraint>(constraintsList.ToArray(), Allocator.Persistent); dilationDistance = new NativeArray <float>(new float[1], Allocator.Persistent); triangleVolumes = new NativeArray <float>(new float[tris.Length], Allocator.Persistent); triangleSurfaceAreas = new NativeArray <float>(new float[tris.Length], Allocator.Persistent); volumeAccumulator = new NativeAccumulator <float, Addition>(Allocator.Persistent); areaAccumulator = new NativeAccumulator <float, Addition>(Allocator.Persistent); initialVolume = Verlet.VolumeOfMesh(bodyVerts, bodyTriangles); initialSurfaceArea = Verlet.SurfaceAreaOfMesh(bodyVerts, bodyTriangles); previousDeltaTime = 1f; dilationDistance[0] = 0f; this.scaledGravity = scaledGravity; localToWorld = transform.localToWorldMatrix; worldToLocal = transform.worldToLocalMatrix; groundPlanePos = ground.position; groundPlaneNormal = -ground.forward; this.radius = radius; this.friction = friction; //Set up parallel normal accumulation triangleGraph = new NativeArray <vertexTriangles>(new vertexTriangles[bodyVerts.Length], Allocator.Persistent); for (int i = 0; i < triangleGraph.Length; i++) { triangleGraph[i] = new vertexTriangles(-1); } for (int i = 0; i < tris.Length; i++) { triangleGraph[tris[i].x] = triangleGraph[tris[i].x].Add(tris[i]); triangleGraph[tris[i].y] = triangleGraph[tris[i].y].Add(tris[i]); triangleGraph[tris[i].z] = triangleGraph[tris[i].z].Add(tris[i]); } //Set up parallel constraint satisfaction connectionGraph = new NativeArray <vertexConstraints>(new vertexConstraints[bodyVerts.Length], Allocator.Persistent); for (int i = 0; i < connectionGraph.Length; i++) { connectionGraph[i] = new vertexConstraints(); } for (int i = 0; i < constraintsArray.Length; i++) { Verlet.DistConstraint constraint = constraintsArray[i]; connectionGraph[constraint.index1] = connectionGraph[constraint.index1].Add(constraint); int temp = constraint.index1; constraint.index1 = constraint.index2; constraint.index2 = temp; connectionGraph[constraint.index1] = connectionGraph[constraint.index1].Add(constraint); } }