예제 #1
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);
    }
예제 #2
0
    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);
    }