- Cal3D 0.11 API Reference -

quaternion.h

00001 //****************************************************************************//
00002 // quaternion.h                                                               //
00003 // Copyright (C) 2001, 2002 Bruno 'Beosil' Heidelberger                       //
00004 //****************************************************************************//
00005 // This library is free software; you can redistribute it and/or modify it    //
00006 // under the terms of the GNU Lesser General Public License as published by   //
00007 // the Free Software Foundation; either version 2.1 of the License, or (at    //
00008 // your option) any later version.                                            //
00009 //****************************************************************************//
00010 
00011 #ifndef CAL_QUATERNION_H
00012 #define CAL_QUATERNION_H
00013 
00014 //****************************************************************************//
00015 // Includes                                                                   //
00016 //****************************************************************************//
00017 
00018 #include "cal3d/global.h"
00019 #include "cal3d/vector.h"
00020 
00021 //****************************************************************************//
00022 // Forward declarations                                                       //
00023 //****************************************************************************//
00024 
00025 //class CalVector;
00026 
00027 //****************************************************************************//
00028 // Class declaration                                                          //
00029 //****************************************************************************//
00030 
00031  /*****************************************************************************/
00035 class CAL3D_API CalQuaternion
00036 {
00037     // member variables
00038 public:
00039     float x;
00040     float y;
00041     float z;
00042     float w;
00043     
00044     // constructors/destructor
00045 public:
00046     inline CalQuaternion() : x(0.0f), y(0.0f), z(0.0f), w(1.0f){};
00047     inline CalQuaternion(const CalQuaternion& q): x(q.x), y(q.y), z(q.z), w(q.w) {};
00048     inline CalQuaternion(float qx, float qy, float qz, float qw): x(qx), y(qy), z(qz), w(qw) {};
00049     inline ~CalQuaternion() {};
00050     
00051     // member functions 
00052 public:
00053     inline float& operator[](unsigned int index)
00054     {
00055         return (&x)[index];
00056     }
00057     
00058     inline const float& operator[](unsigned int index) const
00059     {
00060         return (&x)[index];
00061     }   
00062     
00063     inline void operator=(const CalQuaternion& q)
00064         {
00065         x = q.x;
00066         y = q.y;
00067         z = q.z;
00068         w = q.w;
00069     }
00070     
00071     inline void operator*=(const CalQuaternion& q)
00072     {
00073         float qx, qy, qz, qw;
00074         qx = x;
00075         qy = y;
00076         qz = z;
00077         qw = w;
00078         
00079         x = qw * q.x + qx * q.w + qy * q.z - qz * q.y;
00080         y = qw * q.y - qx * q.z + qy * q.w + qz * q.x;
00081         z = qw * q.z + qx * q.y - qy * q.x + qz * q.w;
00082         w = qw * q.w - qx * q.x - qy * q.y - qz * q.z;
00083     }
00084     
00085     inline void operator*=(const CalVector& v)
00086     {
00087         float qx, qy, qz, qw;
00088         qx = x;
00089         qy = y;
00090         qz = z;
00091         qw = w;
00092         
00093         x = qw * v.x            + qy * v.z - qz * v.y;
00094         y = qw * v.y - qx * v.z            + qz * v.x;
00095         z = qw * v.z + qx * v.y - qy * v.x;
00096         w =          - qx * v.x - qy * v.y - qz * v.z;
00097     }
00098 
00099   inline bool operator==(const CalQuaternion& rhs) const
00100   {
00101     return x == rhs.x &&
00102            y == rhs.y &&
00103            z == rhs.z &&
00104            w == rhs.w;
00105   }
00106 
00107   inline bool operator!=(const CalQuaternion& rhs) const
00108   {
00109     return !operator==(rhs);
00110   }
00111 /*  
00112     static inline CalQuaternion operator*(const CalQuaternion& q, const CalQuaternion& r)
00113     {
00114         return CalQuaternion(
00115             r.w * q.x + r.x * q.w + r.y * q.z - r.z * q.y,
00116             r.w * q.y - r.x * q.z + r.y * q.w + r.z * q.x,
00117             r.w * q.z + r.x * q.y - r.y * q.x + r.z * q.w,
00118             r.w * q.w - r.x * q.x - r.y * q.y - r.z * q.z
00119             );
00120     }
00121 */  
00122     inline void blend(float d, const CalQuaternion& q)
00123     {
00124         float norm;
00125         norm = x * q.x + y * q.y + z * q.z + w * q.w;
00126         
00127         bool bFlip;
00128         bFlip = false;
00129         
00130         if(norm < 0.0f)
00131         {
00132             norm = -norm;
00133             bFlip = true;
00134         }
00135         
00136         float inv_d;
00137         if(1.0f - norm < 0.000001f)
00138         {
00139             inv_d = 1.0f - d;
00140         }
00141         else
00142         {
00143             float theta;
00144             theta = (float) acos(norm);
00145             
00146             float s;
00147             s = (float) (1.0f / sin(theta));
00148             
00149             inv_d = (float) sin((1.0f - d) * theta) * s;
00150             d = (float) sin(d * theta) * s;
00151         }
00152         
00153         if(bFlip)
00154         {
00155             d = -d;
00156         }
00157         
00158         x = inv_d * x + d * q.x;
00159         y = inv_d * y + d * q.y;
00160         z = inv_d * z + d * q.z;
00161         w = inv_d * w + d * q.w;
00162     }
00163     
00164     inline void clear()
00165     {
00166         x = 0.0f;
00167         y = 0.0f;
00168         z = 0.0f;
00169         w = 1.0f;
00170     }
00171     inline void conjugate()
00172     {
00173         x = -x;
00174         y = -y;
00175         z = -z;
00176     }
00177     
00178     inline void invert()
00179     {
00180         conjugate();
00181         const float norm = (x*x) + (y*y) + (z*z) + (w*w);
00182         
00183         if (norm == 0.0f) return;
00184         
00185         const float inv_norm = 1 / norm;
00186         x *= inv_norm;
00187         y *= inv_norm;
00188         z *= inv_norm;
00189         w *= inv_norm;
00190     }
00191     
00192     inline void set(float qx, float qy, float qz, float qw)
00193     {
00194         x = qx;
00195         y = qy;
00196         z = qz;
00197         w = qw;
00198     }
00199 /*  
00200     static inline CalQuaternion shortestArc( const CalVector& from, const CalVector& to )
00201     {
00202         CalVector cross = from % to; //Compute vector cross product
00203         float dot = from * to ;      //Compute dot product
00204         
00205         dot = (float) sqrt( 2*(dot+1) ) ; //We will use this equation twice
00206         
00207         cross /= dot ; //Get the x, y, z components
00208         
00209         //Return with the w component (Note that w is inverted because Cal3D has
00210         // left-handed rotations )
00211         return CalQuaternion( cross[0], cross[1], cross[2], -dot/2 ) ; 
00212         
00213     }
00214 
00215   */
00216 };
00217 
00218 
00219 static inline CalQuaternion operator*(const CalQuaternion& q, const CalQuaternion& r)
00220 {
00221     return CalQuaternion(
00222         r.w * q.x + r.x * q.w + r.y * q.z - r.z * q.y,
00223         r.w * q.y - r.x * q.z + r.y * q.w + r.z * q.x,
00224         r.w * q.z + r.x * q.y - r.y * q.x + r.z * q.w,
00225         r.w * q.w - r.x * q.x - r.y * q.y - r.z * q.z
00226         );
00227 }
00228 
00229 static inline CalQuaternion shortestArc( const CalVector& from, const CalVector& to )
00230 {
00231     CalVector cross = from % to; //Compute vector cross product
00232     float dot = from * to ;      //Compute dot product
00233     
00234     dot = (float) sqrt( 2*(dot+1) ) ; //We will use this equation twice
00235     
00236     cross /= dot ; //Get the x, y, z components
00237     
00238     //Return with the w component (Note that w is inverted because Cal3D has
00239     // left-handed rotations )
00240     return CalQuaternion( cross[0], cross[1], cross[2], -dot/2 ) ; 
00241     
00242 }
00243 
00244 
00245 #endif
00246 
00247 //****************************************************************************//

Generated at Thu Jun 29 19:03:59 2006 by The Cal3D Team with Doxygen 1.4.6