00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef _QUAT_H_
00014 #define _QUAT_H_
00015
00016 #include <vrs/vertexdata.h>
00017 #include <vrs/vector.h>
00018 #include <vrs/matrix.h>
00019
00020 namespace VRS {
00021
00022 typedef VertexData<4, double> Vector4d;
00023
00025 class VRS_CORE_API Quat : public VertexData<4, double>
00026 {
00027
00028 public:
00029
00030
00031
00032 inline Quat() : Vector4d(0.0, 0.0, 0.0, 1.0) {}
00033
00034 inline Quat( double x, double y, double z, double w ) : Vector4d(x, y, z, w) {}
00035
00036 inline Quat( const Vector4d &v ) : Vector4d(v) {}
00037
00038 inline Quat( double angle, const Vector& axis)
00039 {
00040 makeRotate(angle,axis);
00041 }
00042
00043 inline Quat( double angle1, const Vector& axis1,
00044 double angle2, const Vector& axis2,
00045 double angle3, const Vector& axis3)
00046 {
00047 makeRotate(angle1,axis1,angle2,axis2,angle3,axis3);
00048 }
00049
00050 inline bool operator == (const Quat& v) const { return Vector4d::operator==(v); }
00051
00052 inline bool operator != (const Quat& v) const { return Vector4d::operator!=(v); }
00053
00054 inline bool operator < (const Quat& v) const { return Vector4d::operator<(v); }
00055
00056
00057
00058
00059
00060 inline Vector toVec3d() const
00061 {
00062 return Vector(data_[0], data_[1], data_[2]);
00063 }
00064
00065 inline void set(double x, double y, double z, double w)
00066 {
00067 data_[0] = x;
00068 data_[1] = y;
00069 data_[2] = z;
00070 data_[3] = w;
00071 }
00072
00073 void set(const Matrix &matrix);
00074 void get(Matrix &matrix) const;
00075
00076 void set(const Vector &dir, const Vector &up);
00077 void get(Vector &dir, Vector &up) const;
00078
00079 inline double & x() { return data_[0]; }
00080 inline double & y() { return data_[1]; }
00081 inline double & z() { return data_[2]; }
00082 inline double & w() { return data_[3]; }
00083
00084 inline double x() const { return data_[0]; }
00085 inline double y() const { return data_[1]; }
00086 inline double z() const { return data_[2]; }
00087 inline double w() const { return data_[3]; }
00088
00090 bool zeroRotation() const { return data_[0]==0.0 && data_[1]==0.0 && data_[2]==0.0 && data_[3]==1.0; }
00091
00092
00093
00094
00095
00096
00097
00098
00099
00101 inline const Quat operator * (double rhs) const
00102 {
00103 return Quat(data_[0]*rhs, data_[1]*rhs, data_[2]*rhs, data_[3]*rhs);
00104 }
00105
00107 inline Quat& operator *= (double rhs)
00108 {
00109 data_[0] *= rhs;
00110 data_[1] *= rhs;
00111 data_[2] *= rhs;
00112 data_[3] *= rhs;
00113 return *this;
00114 }
00115
00117 inline const Quat operator*(const Quat& rhs) const
00118 {
00119 return Quat( rhs.data_[3]*data_[0] + rhs.data_[0]*data_[3] + rhs.data_[1]*data_[2] - rhs.data_[2]*data_[1],
00120 rhs.data_[3]*data_[1] - rhs.data_[0]*data_[2] + rhs.data_[1]*data_[3] + rhs.data_[2]*data_[0],
00121 rhs.data_[3]*data_[2] + rhs.data_[0]*data_[1] - rhs.data_[1]*data_[0] + rhs.data_[2]*data_[3],
00122 rhs.data_[3]*data_[3] - rhs.data_[0]*data_[0] - rhs.data_[1]*data_[1] - rhs.data_[2]*data_[2] );
00123 }
00124
00126 inline Quat& operator*=(const Quat& rhs)
00127 {
00128 double x = rhs.data_[3]*data_[0] + rhs.data_[0]*data_[3] + rhs.data_[1]*data_[2] - rhs.data_[2]*data_[1];
00129 double y = rhs.data_[3]*data_[1] - rhs.data_[0]*data_[2] + rhs.data_[1]*data_[3] + rhs.data_[2]*data_[0];
00130 double z = rhs.data_[3]*data_[2] + rhs.data_[0]*data_[1] - rhs.data_[1]*data_[0] + rhs.data_[2]*data_[3];
00131 data_[3] = rhs.data_[3]*data_[3] - rhs.data_[0]*data_[0] - rhs.data_[1]*data_[1] - rhs.data_[2]*data_[2];
00132
00133 data_[2] = z;
00134 data_[1] = y;
00135 data_[0] = x;
00136
00137 return (*this);
00138 }
00139
00141 inline Quat operator / (double rhs) const
00142 {
00143 double div = 1.0/rhs;
00144 return Quat(data_[0]*div, data_[1]*div, data_[2]*div, data_[3]*div);
00145 }
00146
00148 inline Quat& operator /= (double rhs)
00149 {
00150 double div = 1.0/rhs;
00151 data_[0] *= div;
00152 data_[1] *= div;
00153 data_[2] *= div;
00154 data_[3] *= div;
00155 return *this;
00156 }
00157
00159 inline const Quat operator/(const Quat& denom) const
00160 {
00161 return ( (*this) * denom.inverse() );
00162 }
00163
00165 inline Quat& operator/=(const Quat& denom)
00166 {
00167 (*this) = (*this) * denom.inverse();
00168 return (*this);
00169 }
00170
00172 inline const Quat operator + (const Quat& rhs) const
00173 {
00174 return Quat(data_[0]+rhs.data_[0], data_[1]+rhs.data_[1],
00175 data_[2]+rhs.data_[2], data_[3]+rhs.data_[3]);
00176 }
00177
00179 inline Quat& operator += (const Quat& rhs)
00180 {
00181 data_[0] += rhs.data_[0];
00182 data_[1] += rhs.data_[1];
00183 data_[2] += rhs.data_[2];
00184 data_[3] += rhs.data_[3];
00185 return *this;
00186 }
00187
00189 inline const Quat operator - (const Quat& rhs) const
00190 {
00191 return Quat(data_[0]-rhs.data_[0], data_[1]-rhs.data_[1],
00192 data_[2]-rhs.data_[2], data_[3]-rhs.data_[3] );
00193 }
00194
00196 inline Quat& operator -= (const Quat& rhs)
00197 {
00198 data_[0] -= rhs.data_[0];
00199 data_[1] -= rhs.data_[1];
00200 data_[2] -= rhs.data_[2];
00201 data_[3] -= rhs.data_[3];
00202 return *this;
00203 }
00204
00207 inline const Quat operator - () const
00208 {
00209 return Quat (-data_[0], -data_[1], -data_[2], -data_[3]);
00210 }
00211
00213 double abs() const
00214 {
00215 return sqrt( data_[0]*data_[0] + data_[1]*data_[1] + data_[2]*data_[2] + data_[3]*data_[3]);
00216 }
00217
00219 double abs2() const
00220 {
00221 return data_[0]*data_[0] + data_[1]*data_[1] + data_[2]*data_[2] + data_[3]*data_[3];
00222 }
00223
00225 inline Quat conj() const
00226 {
00227 return Quat( -data_[0], -data_[1], -data_[2], data_[3] );
00228 }
00229
00231 inline const Quat inverse () const
00232 {
00233 return conj() / abs2();
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 void makeRotate( double angle,
00247 double x, double y, double z );
00248 void makeRotate ( double angle, const Vector& vec );
00249
00250 void makeRotate ( double angle1, const Vector& axis1,
00251 double angle2, const Vector& axis2,
00252 double angle3, const Vector& axis3);
00253
00259 void makeRotate(const Vector &vec1, const Vector &vec2 );
00260
00262 void getRotate(double &angle, double &x, double &y, double &z ) const;
00263
00265 void getRotate(double &angle, Vector &vec ) const;
00266
00269 void slerp(double t, const Quat &from, const Quat &to);
00270
00272 Vector operator*(const Vector& v) const
00273 {
00274
00275 Vector uv, uuv;
00276 Vector qvec(data_[0], data_[1], data_[2]);
00277 uv = qvec * v;
00278 uuv = qvec * uv;
00279 uv *= ( 2.0f * data_[3] );
00280 uuv *= 2.0f;
00281 return v + uv + uuv;
00282 }
00283
00284 friend inline std::ostream& operator << (std::ostream& output, const Quat& vec);
00285
00286 VRS_SERIALIZABLE_NO_SO_CLASS(Quat);
00287
00288 protected:
00289
00290 };
00291
00292 inline std::ostream& operator << (std::ostream& output, const Quat& vec)
00293 {
00294 output << vec.data_[0] << " "
00295 << vec.data_[1] << " "
00296 << vec.data_[2] << " "
00297 << vec.data_[3];
00298 return output;
00299 }
00300
00301 }
00302
00303 #endif
00304