Example #1
0
    }       // End of Slerp()

    //-------------------------------------------------------------------------------
    // @ ApproxSlerp()
    //-------------------------------------------------------------------------------
    // Approximate spherical linear interpolation of two quaternions
    // Based on "Hacking Quaternions", Jonathan Blow, Game Developer, March 2002.
    // See Game Developer, February 2004 for an alternate method.
    //-------------------------------------------------------------------------------
    public IvQuat ApproxSlerp(ref IvQuat start, ref IvQuat end, float t)
    {
        float cosTheta = start.Dot(end);

        // correct time by using cosine of angle between quaternions
        float factor = 1.0f - 0.7878088f * cosTheta;
        float k      = 0.5069269f;

        factor *= factor;
        k      *= factor;

        float b = 2 * k;
        float c = -3 * k;
        float d = 1 + k;

        t = t * (b * t + c) + d;

        // initialize result
        IvQuat result = t * end;

        // if "angle" between quaternions is less than 90 degrees
        if (cosTheta >= ML.Util.kEpsilon)
        {
            // use standard interpolation
            result += (1.0f - t) * start;
        }
        else
        {
            // otherwise, take the shorter path
            result += (t - 1.0f) * start;
        }

        return(result);
    }       // End of ApproxSlerp()
Example #2
0
    }       // End of Lerp()

    //-------------------------------------------------------------------------------
    // @ Slerp()
    //-------------------------------------------------------------------------------
    // Spherical linearly interpolate two quaternions
    // This will always take the shorter path between them
    //-------------------------------------------------------------------------------
    public IvQuat Slerp(ref IvQuat start, ref IvQuat end, float t)
    {
        // get cosine of "angle" between quaternions
        float cosTheta = start.Dot(end);
        float startInterp, endInterp;

        // if "angle" between quaternions is less than 90 degrees
        if (cosTheta >= ML.Util.kEpsilon)
        {
            // if angle is greater than zero
            if ((1.0f - cosTheta) > ML.Util.kEpsilon)
            {
                // use standard slerp
                float theta         = Mathf.Acos(cosTheta);
                float recipSinTheta = 1.0f / Mathf.Sin(theta);

                startInterp = Mathf.Sin((1.0f - t) * theta) * recipSinTheta;
                endInterp   = Mathf.Sin(t * theta) * recipSinTheta;
            }
            // angle is close to zero
            else
            {
                // use linear interpolation
                startInterp = 1.0f - t;
                endInterp   = t;
            }
        }
        // otherwise, take the shorter route
        else
        {
            // if angle is less than 180 degrees
            if ((1.0f + cosTheta) > ML.Util.kEpsilon)
            {
                // use slerp w/negation of start quaternion
                float theta         = Mathf.Acos(-cosTheta);
                float recipSinTheta = 1.0f / Mathf.Sin(theta);

                startInterp = Mathf.Sin((t - 1.0f) * theta) * recipSinTheta;
                endInterp   = Mathf.Sin(t * theta) * recipSinTheta;
            }
            // angle is close to 180 degrees
            else
            {
                // use lerp w/negation of start quaternion
                startInterp = t - 1.0f;
                endInterp   = t;
            }
        }

        return(startInterp * start + endInterp * end);
    }       // End of Slerp()
Example #3
0
    }       // End of IvQuat::Rotate()

    //-------------------------------------------------------------------------------
    // @ Lerp()
    //-------------------------------------------------------------------------------
    // Linearly interpolate two quaternions
    // This will always take the shorter path between them
    //-------------------------------------------------------------------------------
    public IvQuat Lerp(ref IvQuat start, ref IvQuat end, float t)
    {
        // get cos of "angle" between quaternions
        float cosTheta = start.Dot(end);

        // initialize result
        IvQuat result = t * end;

        // if "angle" between quaternions is less than 90 degrees
        if (cosTheta >= ML.Util.kEpsilon)
        {
            // use standard interpolation
            result += (1.0f - t) * start;
        }
        else
        {
            // otherwise, take the shorter path
            result += (t - 1.0f) * start;
        }

        return(result);
    }       // End of Lerp()