コード例 #1
0
ファイル: Softbody.cs プロジェクト: superowner/MathUtilities
    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);
    }
コード例 #2
0
        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;
        }
コード例 #3
0
    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);
    }
コード例 #4
0
    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");
    }
コード例 #5
0
    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);
    }
コード例 #6
0
        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);
            }
        }