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 ); }