Exemplo n.º 1
0
    void constrainVertsToDeformation(Vector3[] originalVerts, Matrix4x4 rigidOrigToBody, ref NativeArray <Vector3> bodyVerts)
    {
        Matrix4x4 bodyToOrig = rigidOrigToBody.inverse;

        for (int i = 0; i < bodyVerts.Length; i++)
        {
            bodyVerts[i] = Vector3.Lerp(bodyToOrig.MultiplyPoint3x4(bodyVerts[i]), originalVerts[i], stiffness);
        }

        //Do a bunch of fitting iterations
        float alpha = 0.45f;

        for (int i = 0; i < 5; i++)
        {
            optimizer.Add(xScale, "xScale");
            optimizer.Add(yBasis, "yBasis");
            optimizer.Add(zBasis, "zBasis");
            xScale -= optimizer.CalcErrorDerivative("xScale") * alpha;
            yBasis -= optimizer.CalcErrorGradient("yBasis") * alpha;
            zBasis -= optimizer.CalcErrorGradient("zBasis") * alpha;

            //Prevent shape from inverting
            if (xScale < 0f)
            {
                xScale *= -1f; yBasis *= -1f;
            }
        }

        //xScale = Mathf.Lerp(xScale, 1f, stiffness);
        //yBasis = Vector3.Lerp(yBasis, yBasis.normalized, stiffness);
        //zBasis = Vector3.Lerp(zBasis, zBasis.normalized, stiffness);

        //Do Volume Preservation Stuff
        Vector3 xBasis = Vector3.Cross(yBasis, zBasis).normalized *xScale;

        for (int i = 0; i < bodyVerts.Length; i++)
        {
            DualVector3 deformedOriginal = (xBasis.normalized * Vector3.Dot(xBasis, originalVerts[i])) +
                                           (yBasis.normalized * Vector3.Dot(yBasis, originalVerts[i])) +
                                           (zBasis.normalized * Vector3.Dot(zBasis, originalVerts[i]));

            bodyVerts[i] = rigidOrigToBody.MultiplyPoint3x4(deformedOriginal);
        }
    }
    void Update()
    {
        baseTransformMatrix = new DualMatrix4x3(baseTransform.position, baseTransform.rotation, baseTransform.localScale);

        //Set up the variables to optimize
        optimizer.Add(transform.position, "position");
        optimizer.Add(transform.up, "yBasis");
        optimizer.Add(transform.forward, "zBasis");
        optimizer.Add(transform.localScale, "scale");
        optimizer.CalculateErrorDerivative = CalculateErrorDerivative;

        //Calculate and Apply the Instantaneous Gradients at this point in time
        transform.position -= optimizer.CalcErrorGradient("position") * alpha;

        Vector3 forwardBasis = transform.forward - (optimizer.CalcErrorGradient("zBasis") * alpha);
        Vector3 upBasis      = transform.up - (optimizer.CalcErrorGradient("yBasis") * alpha);

        transform.rotation = Quaternion.LookRotation(forwardBasis, upBasis);

        transform.localScale -= optimizer.CalcErrorGradient("scale") * alpha;
    }