00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __CS_QUATERNION_H__
00020 #define __CS_QUATERNION_H__
00021
00022 #include "csgeom/math3d.h"
00023
00027 class csQuaternion
00028 {
00029 public:
00031 inline void Init (float theR, float theX, float theY, float theZ)
00032 { r = theR; x = theX; y = theY; z = theZ; }
00033
00035 csQuaternion () { Init(0, 0, 0, 0 ); }
00037 csQuaternion (float theR, float theX=0.0, float theY=0.0, float theZ=0.0)
00038 { Init (theR, theX, theY, theZ ); }
00040 csQuaternion (const csQuaternion& q) { Init (q.r, q.x, q.y, q.z); }
00042 csQuaternion (const csVector3& q) { Init (0, q.x, q.y, q.z); }
00043
00045 inline friend csQuaternion operator+ (const csQuaternion& q1, const csQuaternion& q2)
00046 { return csQuaternion (q1.r + q2.r, q1.x + q2.x, q1.y + q2.y, q1.z + q2.z ); }
00048 inline friend csQuaternion operator- (const csQuaternion& q1, const csQuaternion& q2)
00049 { return csQuaternion (q1.r - q2.r, q1.x - q2.x, q1.y - q2.y, q1.z - q2.z ); }
00051 inline friend csQuaternion operator* (const csQuaternion& q1, const csQuaternion& q2)
00052 { return csQuaternion (q1.r*q2.r - q1.x*q2.x - q1.y*q2.y - q1.z*q2.z,
00053 q1.y*q2.z - q1.z*q2.y + q1.r*q2.x + q1.x*q2.r,
00054 q1.z*q2.x - q1.x*q2.z + q1.r*q2.y + q1.y*q2.r,
00055 q1.x*q2.y - q1.y*q2.x + q1.r*q2.z + q1.z*q2.r); }
00056
00058 csQuaternion& operator*= (const csQuaternion& q2)
00059 {
00060 Init (r*q2.r - x*q2.x - y*q2.y - z*q2.z,
00061 y*q2.z - z*q2.y + r*q2.x + x*q2.r,
00062 z*q2.x - x*q2.z + r*q2.y + y*q2.r,
00063 x*q2.y - y*q2.x + r*q2.z + z*q2.r);
00064 return *this;
00065 }
00066
00068 void Conjugate () { Init (r, -x, -y, -z); }
00069
00071 void Negate () { Init(-r, -x, -y, -z); }
00072
00078 void PrepRotation (float angle, csVector3 vec)
00079 {
00080 double theSin = sin (angle/2);
00081 Init (cos (angle/2), vec.x*theSin, vec.y*theSin, vec.z*theSin);
00082 }
00083
00085 csVector3 Rotate (csVector3 vec)
00086 {
00087 csQuaternion p (vec);
00088 csQuaternion qConj (r, -x, -y, -z);
00089
00090 p = *this * p;
00091 p *= qConj;
00092 return csVector3 (p.x, p.y, p.z);
00093 }
00094
00096 void Normalize ()
00097 {
00098 if(x*x + y*y + z*z > .999)
00099 {
00100
00101 float inverselen = 1.0/(x*x + y*y + z*z);
00102 x *= inverselen;
00103 y *= inverselen;
00104 z *= inverselen;
00105 r = 0.0;
00106 }
00107 else
00108 {
00109 r = sqrt(1.0 - x*x - y*y - z*z);
00110 }
00111 }
00112
00118 void SetWithEuler(const csVector3 &rot);
00119
00123 csQuaternion ToAxisAngle() const;
00124
00130 csQuaternion Slerp (const csQuaternion &quat2, float slerp) const;
00131
00132
00133
00134 float r,x,y,z;
00135 };
00136
00137
00138 #endif // __CS_QUATERNION_H__