7 #ifndef __math_Quaternion_h__ 8 #define __math_Quaternion_h__ 13 #define FE_SLERP_DELTA (1e-6f) 14 #define FE_QUAT_DELTA (1e-6f) 15 #define FE_ALMOST1 (1.0f-FE_SLERP_DELTA) 46 void computeAngleAxis(T &radians,
Vector<3,T>& axis)
const;
55 set(*
this,0.0f,0.0f,0.0f,1.0f);
68 set(*
this,radians,axis);
74 set(*
this,radians,axis);
92 set(*
this,other[0],other[1],other[2],other[3]);
99 T len=(*this)[0]*(*this)[0]+(*this)[1]*(*this)[1]+(*this)[2]*(*this)[2];
102 set(axis,0.0f,0.0f,1.0f);
107 T inv=1.0f/sqrt(len);
111 set(axis,(*this)[0]*inv,(*this)[1]*inv,(*this)[2]*inv);
113 radians=2.0f*acos(fabs((*
this)[3]));
114 if(FE_INVALID_SCALAR(radians))
131 set(*pVector,T(0),T(0),T(0),T(1));
141 template<
class T,
class X,
class Y,
class Z,
class W>
145 set(*pVector,x,y,z,w);
165 template<
class T,
class U>
169 setAt(*pVector,index,value);
179 template<
class T,
class U>
183 if(fabs(axis[0])+fabs(axis[1])+fabs(axis[2])<FE_QUAT_DELTA)
189 T halfAngle=radians*0.5f;
192 set(result,temp[0],temp[1],temp[2],cos(halfAngle));
200 template<
class T,
class U>
203 T halfAngle=radians*0.5f;
205 set(result,0.0f,0.0f,0.0f,cos(halfAngle));
206 setAt(result,axis,sin(halfAngle));
223 FEASSERT(fabs(magnitudeSquared(from)-1.0)<1e-3);
224 FEASSERT(fabs(magnitudeSquared(to)-1.0)<1e-3);
226 T tx,ty,tz,temp,dist;
233 if (cost > FE_ALMOST1)
238 if (cost < -FE_ALMOST1)
249 T len=sqrt(ty*ty + tz*tz);
251 if (len < FE_SLERP_DELTA)
260 temp=tx*tx + ty*ty + tz*tz;
262 dist=1.0f/sqrt(temp);
268 set(result,tx,ty,tz,0.0f);
273 tx=from[1]*to[2] - from[2]*to[1];
274 ty=from[2]*to[0] - from[0]*to[2];
275 tz=from[0]*to[1] - from[1]*to[0];
277 temp=tx*tx + ty*ty + tz*tz;
279 dist=1.0f/sqrt(temp);
286 temp=0.5f * (1.0f - cost);
296 set(result,tx,ty,tz,sqrt(0.5f * (1.0f + cost)));
318 template<
class T,
class U>
323 return lhs=temp*scale;
338 set(lhs,-lhs[0],-lhs[1],-lhs[2],-lhs[3]);
351 set(lhs,-clhs[0],-clhs[1],-clhs[2],clhs[3]);
363 set(inverse,-lhs[0],-lhs[1],-lhs[2],lhs[3]);
375 s.
sPrintf(
"%g %g %g %g",lhs[0],lhs[1],lhs[2],lhs[3]);
387 for(U32 i=0; i<4; i++)
401 return( !FE_INVALID_SCALAR(lhs[0]) &&
402 !FE_INVALID_SCALAR(lhs[1]) &&
403 !FE_INVALID_SCALAR(lhs[2]) &&
404 !FE_INVALID_SCALAR(lhs[3]) &&
405 !FE_INVALID_SCALAR(rhs[0]) &&
406 !FE_INVALID_SCALAR(rhs[1]) &&
407 !FE_INVALID_SCALAR(rhs[2]) &&
408 !FE_INVALID_SCALAR(rhs[3]) &&
409 fabs(rhs[0]-lhs[0]) < margin &&
410 fabs(rhs[1]-lhs[1]) < margin &&
411 fabs(rhs[2]-lhs[2]) < margin &&
412 fabs(rhs[3]-lhs[3]) < margin);
424 set(sum, lhs[3]*rhs[0]+lhs[0]*rhs[3]+lhs[1]*rhs[2]-lhs[2]*rhs[1],
425 lhs[3]*rhs[1]+lhs[1]*rhs[3]+lhs[2]*rhs[0]-lhs[0]*rhs[2],
426 lhs[3]*rhs[2]+lhs[2]*rhs[3]+lhs[0]*rhs[1]-lhs[1]*rhs[0],
427 lhs[3]*rhs[3]-lhs[0]*rhs[0]-lhs[1]*rhs[1]-lhs[2]*rhs[2]);
435 template<
class T,
class U>
445 template<
class T,
class U>
453 lhs.computeAngleAxis(angle,axis);
454 set(sum,angle*rhs,axis);
458 template <
typename T>
464 mid[0]= lhs[3]*in[0]+lhs[1]*in[2]-lhs[2]*in[1];
465 mid[1]= lhs[3]*in[1]+lhs[2]*in[0]-lhs[0]*in[2];
466 mid[2]= lhs[3]*in[2]+lhs[0]*in[1]-lhs[1]*in[0];
467 mid[3]= -lhs[0]*in[0]-lhs[1]*in[1]-lhs[2]*in[2];
470 -mid[3]*lhs[0]+mid[0]*lhs[3]-mid[1]*lhs[2]+mid[2]*lhs[1],
471 -mid[3]*lhs[1]+mid[1]*lhs[3]-mid[2]*lhs[0]+mid[0]*lhs[2],
472 -mid[3]*lhs[2]+mid[2]*lhs[3]-mid[0]*lhs[1]+mid[1]*lhs[0]);
475 template <
typename T>
480 x*(lhs[0]*lhs[0]+lhs[3]*lhs[3]-lhs[2]*lhs[2]-lhs[1]*lhs[1]),
481 2.0*x*(lhs[0]*lhs[1]+lhs[2]*lhs[3]),
482 2.0*x*(lhs[0]*lhs[2]-lhs[1]*lhs[3]));
485 template <
typename T>
490 2.0*y*(lhs[0]*lhs[1]-lhs[2]*lhs[3]),
491 y*(lhs[1]*lhs[1]+lhs[3]*lhs[3]-lhs[0]*lhs[0]-lhs[2]*lhs[2]),
492 2.0*y*(lhs[0]*lhs[3]+lhs[1]*lhs[2]));
495 template <
typename T>
500 2.0*z*(lhs[0]*lhs[2]+lhs[3]*lhs[1]),
501 2.0*z*(lhs[2]*lhs[1]-lhs[0]*lhs[3]),
502 z*(lhs[2]*lhs[2]+lhs[3]*lhs[3]-lhs[1]*lhs[1]-lhs[0]*lhs[0]));
516 result=from+fraction*(to-from);
539 cosom = from[0]*to[0]+
564 if ( (1.0f - cosom) > FE_SLERP_DELTA )
567 T omega = acos(cosom);
568 T sinom = sin(omega);
569 scale0 = sin((1.0f-fraction) * omega) / sinom;
570 scale1 = sin(fraction * omega) / sinom;
577 scale0 = 1.0f-fraction;
582 set(result, scale0*from[0] + scale1*copy[0],
583 scale0*from[1] + scale1*copy[1],
584 scale0*from[2] + scale1*copy[2],
585 scale0*from[3] + scale1*copy[3]);
597 rotateVector(rRotation,yAxis,rotated);
599 FEASSERT(rotated[0]!=0.0f);
600 Real angle=atan2(rotated[2],rotated[1]);
603 set(qinv,-angle,e_xAxis);
619 rotateVector(rRotation,zAxis,rotated);
621 FEASSERT(rotated[0]!=0.0f);
622 Real angle=atan2(rotated[0],rotated[2]);
625 set(qinv,-angle,e_yAxis);
641 rotateVector(rRotation,xAxis,rotated);
643 FEASSERT(rotated[0]!=0.0f);
644 Real angle=atan2(rotated[1],rotated[0]);
647 set(qinv,-angle,e_zAxis);
673 FE_DL_PUBLIC SpatialQuaternion
stepVelocity(
const SpatialQuaternion& previous,
674 const SpatialQuaternion& desired,
675 Real deltaT,Real maxVelocity, Real maxAcceleration);
Quaternion< T > & invert(Quaternion< T > &lhs)
Reverse the direction of rotation (and retain the magnitude)
Definition: Quaternion.h:348
bool operator==(const Quaternion< T > &lhs, const Quaternion< T > &rhs)
Equality test.
Definition: Quaternion.h:385
Matrix for 3D transformations.
Definition: Matrix3x4.h:47
SpatialQuaternion stepVelocity(const SpatialQuaternion &previous, const SpatialQuaternion &desired, Real deltaT, Real maxVelocity, Real maxAcceleration)
Return a new velocity based on desired change and constraints.
Definition: Quaternion.cc:14
kernel
Definition: namespace.dox:3
Quaternion< T > & forcePositiveW(Quaternion< T > &lhs)
Negate all elements if W is negative.
Definition: Quaternion.h:334
Quaternion< T > & normalize(Quaternion< T > &result)
Normalize all four components.
Definition: Quaternion.h:154
Quaternion< T > & nlerp(Quaternion< T > &result, const Quaternion< T > &from, const Quaternion< T > &to, T fraction)
Generate a rotation that in between two other rotations.
Definition: Quaternion.h:513
Dense vector - size fixed by template.
Definition: Vector.h:19
String print(const Quaternion< T > &lhs)
Print to a string.
Definition: Quaternion.h:372
Quaternion< T > & operator*=(Quaternion< T > &lhs, U scale)
Scale in place.
Definition: Quaternion.h:319
String & sPrintf(const char *fmt,...)
Populate the string in the manner of sprintf().
Definition: String.cc:529
Automatically reference-counted string container.
Definition: String.h:128
Quaternion< T > operator*(const Quaternion< T > &lhs, const U &rhs)
Scale the rotation angle.
Definition: Quaternion.h:446
Quaternion< T > & slerp(Quaternion< T > &result, const Quaternion< T > &from, const Quaternion< T > &to, T fraction)
Generate a rotation that in between two other rotations.
Definition: Quaternion.h:531
Quaternion< T > & setAt(Quaternion< T > &lhs, U32 index, U value)
Set the value at the index.
Definition: Quaternion.h:166
Quaternion< T > operator-(const Quaternion< T > &lhs)
Return the inverse rotation.
Definition: Quaternion.h:360
Quaternion< T > operator*(const Quaternion< T > &lhs, const Quaternion< T > &rhs)
Multiply two quaternions.
Definition: Quaternion.h:420
Partially specialized 4-component vector intended for spatial use.
Definition: Vector4.h:21
Four-dimensional complex number.
Definition: Quaternion.h:32
bool equivalent(const Quaternion< T > &lhs, const Quaternion< T > &rhs, T margin)
Equivalence test within the given tolerance margin.
Definition: Quaternion.h:398
Quaternion< T > & operator*=(Quaternion< T > &lhs, const Quaternion< T > &rhs)
Multiply in place.
Definition: Quaternion.h:307
Quaternion< T > operator*(const U &lhs, const Quaternion< T > &rhs)
Scale the rotation angle.
Definition: Quaternion.h:436