Ejemplo n.º 1
0
    VOID Quaternion::slerp( F32 t, const Quaternion& from, const Quaternion& to)
	{
		const F32 epsilon = 0.00001f;
		F32 omega, cosomega, sinomega, scale_from, scale_to ;
		
		Quaternion quatTo(to);

		// this is a dot product		
		cosomega = from._v[0]*to._v[0] + from._v[1]*to._v[1] + from._v[2]*to._v[2] + from._v[3]*to._v[3];
		if ( cosomega < 0.0f )
		{ 
			cosomega = -cosomega; 
			quatTo = -to;
		}
		
		if( (1.0f - cosomega) > epsilon )
		{
			omega= ::acos(cosomega) ;  // 0 <= omega <= Pi (see man acos)
			sinomega = ::sin(omega) ;  // this sinomega should always be +ve so
			// could try sinomega=sqrtf(1-cosomega*cosomega) to avoid a sin()?
			scale_from = ::sin((1.0f-t)*omega)/sinomega ;
			scale_to = ::sin(t*omega)/sinomega ;
		}
		else
		{
			
			// The ends of the vectors are very close
			// we can use simple linear interpolation - no need
			// to worry about the "spherical" interpolation
			scale_from = 1.0f - t ;
			scale_to = t ;
		}
		
		*this = (from*scale_from) + (quatTo*scale_to);
	}           
Ejemplo n.º 2
0
/// Spherical Linear Interpolation
/// As t goes from 0 to 1, the Quat object goes from "from" to "to"
/// Reference: Shoemake at SIGGRAPH 89
/// See also
/// http://www.gamasutra.com/features/programming/19980703/quaternions_01.htm
void ofQuaternion::slerp( float t, const ofQuaternion& from, const ofQuaternion& to ) {
	const double epsilon = 0.00001;
	double omega, cosomega, sinomega, scale_from, scale_to ;

	ofQuaternion quatTo(to);
	// this is a dot product

	cosomega = from.asVec4().dot(to.asVec4());

	if ( cosomega < 0.0 ) {
		cosomega = -cosomega;
		quatTo = -to;
	}

	if ( (1.0 - cosomega) > epsilon ) {
		omega = acos(cosomega) ; // 0 <= omega <= Pi (see man acos)
		sinomega = sin(omega) ;  // this sinomega should always be +ve so
		// could try sinomega=sqrt(1-cosomega*cosomega) to avoid a sin()?
		scale_from = sin((1.0 - t) * omega) / sinomega ;
		scale_to = sin(t * omega) / sinomega ;
	} else {
		/* --------------------------------------------------
		The ends of the vectors are very close
		we can use simple linear interpolation - no need
		to worry about the "spherical" interpolation
		-------------------------------------------------- */
		scale_from = 1.0 - t ;
		scale_to = t ;
	}

	*this = (from * scale_from) + (quatTo * scale_to);

	// so that we get a Vec4
}