示例#1
0
Quat QuatFromSourceToTarget( const Vec3& source, const Vec3& target )
{
    Vec3 s = source.GetNormalized();
    Vec3 t = target.GetNormalized();

    Vec3 c = s.GetCrossProduct( t );
    Real d = s.GetDotProduct( t );

    // check if vectors are the same
    if ( Equals( d, Real( 1 ), REAL_EPSILON * 3 ) )
    {
        // set to no rotation and return
        return Quat::ZERO;
    }

    // check for 180 degree rotation
    Real clen = c.GetLength();
    if ( clen <= REAL_EPSILON )
    {
        // pick an axis to rotate around
        Vec3 r = Vec3::UNIT_Y.GetCrossProduct( source );
        Real rlen = r.GetLength();

        if ( rlen <= REAL_EPSILON )
        {
            // bad luck, pick another axis
            r = Vec3::UNIT_X.GetCrossProduct( source );
            rlen = r.GetLength();
        }

        // normalize, set rotation and return
        r /= rlen;
        return QuatFromAxisAngle( r, Radian( REAL_PI ) );
    }

    // normalize c
    c /= clen;

    // get angle and set quaternion
    Real a = acos( d ) * Real( 0.5 );
    Real sa = sin( a );

    return Quat( cos( a ), c.X() * sa, c.Y() * sa, c.Z() * sa );
}