00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00027
00029
00030 #ifndef __QUATERNION_H__
00031 #define __QUATERNION_H__
00032
00033 #include "H3DApi.h"
00034 #include "H3DBasicTypes.h"
00035 #include "H3DMath.h"
00036 #include "Vec3f.h"
00037
00038 namespace H3D {
00039 namespace ArithmeticTypes {
00040
00041 class Matrix3f;
00042 class Matrix3d;
00043 class Rotation;
00044
00047 class H3DAPI_API Quaternion {
00048 public:
00050 Quaternion(): v( 0, 0, 0 ), w( 0 ) {}
00051
00053 Quaternion( H3DFloat x,
00054 H3DFloat y,
00055 H3DFloat z,
00056 H3DFloat _w ) : v( x, y, z ), w(_w) {}
00057
00059 Quaternion( const Vec3f &_v,
00060 H3DFloat _w ) : v( _v ), w( _w ) {}
00061
00063 explicit Quaternion( const Vec3f &euler_angles );
00064
00066 explicit Quaternion( const Vec3d &euler_angles );
00067
00069 Quaternion( const Rotation &r );
00070
00073 explicit Quaternion( const Matrix3f &m );
00074
00077 explicit Quaternion( const Matrix3d &m );
00078
00080 inline H3DFloat norm() {
00081 return w*w + v.dotProduct( v );
00082 }
00083
00086 inline void normalize() {
00087 H3DFloat n = norm();
00088 if (H3DAbs( n ) > Constants::f_epsilon ) {
00089 H3DFloat length = H3DSqrt( n );
00090 v = v / length;
00091 w = w / length;
00092 }
00093 }
00094
00096 inline H3DFloat dotProduct( const Quaternion &q) const {
00097 return v.x*q.v.x + v.y*q.v.y + v.z*q.v.z + w*q.w;
00098 }
00099
00101 inline Quaternion conjugate() {
00102 return Quaternion( -v, w );
00103 }
00104
00106 inline Quaternion inverse();
00107
00110 Vec3f toEulerAngles();
00111
00115 Quaternion slerp( const Quaternion &q,
00116 H3DFloat t ) const;
00117
00119 Vec3f v;
00121 H3DFloat w;
00122 };
00123
00130
00132 inline ostream& operator<<( ostream &os, const Quaternion &q ) {
00133 os << q.v << " " << q.w;
00134 return os;
00135 }
00136
00138 inline bool operator==( const Quaternion &q1, const Quaternion &q2 ) {
00139 return q1.v == q2.v && q1.w == q2.w;
00140 }
00141
00144 inline Quaternion operator*( const Quaternion &q1,
00145 const Quaternion &q2 ) {
00146 return Quaternion( q1.w * q2.v + q2.w * q1.v + q1.v % q2.v,
00147 q1.w * q2.w - q1.v * q2.v );
00148 }
00149
00151 inline Quaternion operator*( const Quaternion &q,
00152 double d ) {
00153 return Quaternion( d *q.v, (H3DFloat)(d * q.w) );
00154 }
00155
00157 inline Quaternion operator*( const Quaternion &q,
00158 float d ) {
00159 return Quaternion( d *q.v, d * q.w );
00160 }
00161
00163 inline Quaternion operator*( const Quaternion &q,
00164 int d ) {
00165 return Quaternion( d *q.v, (H3DFloat) (d * q.w) );
00166 }
00167
00169 inline Quaternion operator*( const Quaternion &q,
00170 long d ) {
00171 return Quaternion( d *q.v, (H3DFloat) (d * q.w) );
00172 }
00173
00175 inline Quaternion operator*( const float &a,
00176 const Quaternion &b ) {
00177 return b * a;
00178 }
00179
00181 inline Quaternion operator*( const double &a,
00182 const Quaternion &b ) {
00183 return b * a;
00184 }
00185
00187 inline Quaternion operator*( const int &a,
00188 const Quaternion &b ) {
00189 return b * a;
00190 }
00191
00193 inline Quaternion operator*( const long &a,
00194 const Quaternion &b ) {
00195 return b * a;
00196 }
00197
00200 inline Quaternion operator+( const Quaternion &q1,
00201 const Quaternion &q2 ) {
00202 return Quaternion( q1.v + q2.v,
00203 q1.w + q2.w );
00204 }
00206
00208 inline Quaternion operator-( const Quaternion &q ) { return q * -1; }
00209
00212 inline Quaternion operator-( const Quaternion &a, const Quaternion &b ) {
00213 return a + (-b);
00214 }
00215
00217
00218
00219 inline Quaternion Quaternion::inverse() {
00220 H3DFloat n = norm();
00221 if ( H3DAbs(n ) > Constants::f_epsilon ) {
00222 return Quaternion(0,0,0,0);
00223 } else {
00224 return conjugate() / n;
00225 }
00226 }
00227 }
00228 }
00229
00230 #endif