Beispiel #1
0
quaternion quaternion::SlerpExtraSpins(real fT, const quaternion& rkP, const quaternion& rkQ, int iExtraSpins)
{
    real fCos = rkP.Dot(rkQ);
    real fAngle (math::acos(fCos) );

    if (math::abs(fAngle) < msEpsilon )
       return rkP;

    real fSin = math::sin(fAngle);
    real fPhase ( math::pi*iExtraSpins*fT );
    real fInvSin = 1.0f/fSin;
    real fCoeff0 = math::sin((1.0f-fT)*fAngle - fPhase)*fInvSin;
    real fCoeff1 = math::sin(fT*fAngle + fPhase)*fInvSin;
    return fCoeff0*rkP + fCoeff1*rkQ;
}
Beispiel #2
0
quaternion quaternion::nlerp(real fT, const quaternion &rkP, const quaternion &rkQ, bool shortestPath)
{
    quaternion result;
    real fCos = rkP.Dot(rkQ);
    if (fCos < 0.0f && shortestPath)
    {
        result = rkP + fT * ((-rkQ) - rkP);
    }
    else
    {
        result = rkP + fT * (rkQ - rkP);
    }
    result.normalise();
    return result;
}
Beispiel #3
0
quaternion quaternion::Slerp(real fT, const quaternion &rkP, const quaternion &rkQ, bool shortestPath)
{
    real fCos = rkP.Dot(rkQ);
    quaternion rkT;

    // Do we need to invert rotation?
    if (fCos < 0.0f && shortestPath)
    {
        fCos = -fCos;
        rkT = -rkQ;
    }
    else
    {
        rkT = rkQ;
    }

    if (math::abs(fCos) < 1 - msEpsilon)
    {
        // Standard case (slerp)
        real fSin = math::sqrt(1 - fCos*fCos);
        real fAngle = math::atan2(fSin, fCos);
        real fInvSin = 1.0f / fSin;
        real fCoeff0 = math::sin((1.0f - fT) * fAngle) * fInvSin;
        real fCoeff1 = math::sin(fT * fAngle) * fInvSin;
        return fCoeff0 * rkP + fCoeff1 * rkT;
    }
    else
    {
        // There are two situations:
        // 1. "rkP" and "rkQ" are very close (fCos ~= +1), so we can do a linear
        //    interpolation safely.
        // 2. "rkP" and "rkQ" are almost inverse of each other (fCos ~= -1), there
        //    are an infinite number of possibilities interpolation. but we haven't
        //    have method to fix this case, so just use linear interpolation here.
        quaternion t = (1.0f - fT) * rkP + fT * rkT;
        // taking the complement requires renormalisation
        t.normalise();
        return t;
    }
}