00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef __UT_Quaternion_h__
00026 #define __UT_Quaternion_h__
00027
00028 #include "UT_API.h"
00029 #include <SYS/SYS_Math.h>
00030 #include "UT_Vector3.h"
00031
00032 class UT_Matrix3;
00033 class UT_DMatrix3;
00034 class UT_DMatrix4;
00035 class UT_Matrix4;
00036 class UT_XformOrder;
00037 class UT_IStream;
00038
00039 class UT_API UT_Quaternion
00040 {
00041 inline friend UT_Quaternion operator*(const UT_Quaternion&,
00042 const UT_Quaternion&);
00043 inline friend UT_Quaternion operator+(const UT_Quaternion&,
00044 const UT_Quaternion&);
00045 inline friend UT_Quaternion operator-(const UT_Quaternion&,
00046 const UT_Quaternion&);
00047 inline friend UT_Quaternion operator-(const UT_Quaternion&);
00048 inline friend UT_Quaternion operator*(const UT_Quaternion&, fpreal scalar);
00049 inline friend UT_Quaternion operator*(fpreal scalar, const UT_Quaternion&);
00050 inline friend UT_Quaternion operator/(const UT_Quaternion&,
00051 const UT_Quaternion&);
00052 inline friend UT_Quaternion operator/(const UT_Quaternion&, fpreal scalar);
00053
00054 public:
00055 UT_Quaternion(fpreal qx=0, fpreal qy=0,
00056 fpreal qz=0, fpreal qw=0)
00057 {
00058 vec[0] = qx; vec[1] = qy;
00059 vec[2] = qz; vec[3] = qw;
00060 }
00061 UT_Quaternion( fpreal angle,
00062 const UT_Vector3 &axis,
00063 int donormalize=1);
00064 UT_Quaternion(const UT_Quaternion &q)
00065 {
00066 vec[0] = q.vec[0];
00067 vec[1] = q.vec[1];
00068 vec[2] = q.vec[2];
00069 vec[3] = q.vec[3];
00070 }
00071 UT_Quaternion(const UT_Vector3 &rot,
00072 const UT_XformOrder &order)
00073 {
00074 updateFromEuler(rot, order);
00075 }
00076
00077 UT_Quaternion &operator*=(const UT_Quaternion &q);
00078 UT_Quaternion &operator*=(fpreal scalar);
00079 UT_Quaternion &operator/=(const UT_Quaternion &quat);
00080 UT_Quaternion &operator/=(fpreal scalar);
00081 UT_Quaternion &operator+=(const UT_Quaternion &quat);
00082 bool operator==(const UT_Quaternion &quat) const;
00083 bool operator!=(const UT_Quaternion &quat) const;
00084 fpreal operator()(int idx) const
00085 { return vec[idx]; }
00086 float &operator()(int idx)
00087 { return vec[idx]; }
00088 fpreal operator[](int idx) const
00089 { return vec[idx]; }
00090 float &operator[](int idx)
00091 { return vec[idx]; }
00092
00093
00094 bool isEqual(const UT_Quaternion &quat,
00095 fpreal tol = FP32_TOLERANCE) const;
00096
00097
00098 void getRotationMatrix(UT_Matrix3 &mat) const;
00099 void getRotationMatrix(UT_DMatrix3 &mat) const;
00100
00101 void getTransformMatrix(UT_Matrix4 &mat) const;
00102 void getTransformMatrix(UT_DMatrix4 &mat) const;
00103
00104
00105 UT_Quaternion interpolate(const UT_Quaternion &target,
00106 fpreal t, fpreal b = 0.0f) const;
00107
00108 void assign(fpreal qx, fpreal qy,
00109 fpreal qz, fpreal qw)
00110 {
00111 vec[0] = qx; vec[1] = qy;
00112 vec[2] = qz; vec[3] = qw;
00113 }
00114 void identity()
00115 {
00116 vec[0] = vec[1] = vec[2] = 0.0f;
00117 vec[3] = 1.0f;
00118 }
00119 void conjugate()
00120 {
00121 vec[0] = -vec[0];
00122 vec[1] = -vec[1];
00123 vec[2] = -vec[2];
00124 }
00125 void negate()
00126 {
00127 vec[0] = -vec[0];
00128 vec[1] = -vec[1];
00129 vec[2] = -vec[2];
00130 vec[3] = -vec[3];
00131 }
00132 fpreal normal() const
00133 {
00134 return vec[0] * vec[0] +
00135 vec[1] * vec[1] +
00136 vec[2] * vec[2] +
00137 vec[3] * vec[3];
00138 }
00139 void normalize()
00140 {
00141 fpreal dn = normal();
00142 if ( dn != 1.0F )
00143 {
00144 dn = SYSsqrt(dn);
00145 *this /= dn;
00146 }
00147 }
00148 fpreal length() const
00149 {
00150 return SYSsqrt(normal());
00151 }
00152 void invert()
00153 {
00154 fpreal n = 1.0F/normal();
00155 conjugate();
00156 vec[0] *= n;
00157 vec[1] *= n;
00158 vec[2] *= n;
00159 vec[3] *= n;
00160 }
00161
00162
00163
00164 void updateFromVectors(const UT_Vector3 &v1,
00165 const UT_Vector3 &v2);
00166
00167
00168 void updateFromRotationMatrix(const UT_Matrix3 &);
00169 void updateFromRotationMatrix(const UT_DMatrix3 &);
00170
00171
00172 void updateFromAngleAxis(fpreal angle,
00173 const UT_Vector3 &axis,
00174 int normalize=1);
00175
00176 void getAngleAxis(fpreal &angle, UT_Vector3 &axis) const;
00177
00178 void updateFromLogMap(const UT_Vector3 &v);
00179 void getLogMap(UT_Vector3 &v) const;
00180
00181
00182 void updateFromEuler(const UT_Vector3 &rot,
00183 const UT_XformOrder &order);
00184
00185
00186 void computeDerivative(const UT_Vector3 &omega,
00187 UT_Quaternion &q_prime);
00188
00189
00190
00191 UT_Vector3 computeAngVel(const UT_Quaternion &dest,
00192 fpreal time) const;
00193
00194
00195
00196
00197
00198
00199
00200
00201 void integrate(const UT_Vector3 &angvel,
00202 fpreal timestep,
00203 bool accurate = true);
00204
00205
00206
00207 UT_Vector3 computeRotations(const UT_XformOrder &) const;
00208
00209
00210
00211 UT_Vector3 rotate(const UT_Vector3 &) const;
00212
00213
00214
00215 UT_Vector3 rotateInverse(const UT_Vector3 &) const;
00216
00217
00218
00219
00220
00221 void multAngle( fpreal s );
00222
00223 float &x() { return vec[0]; }
00224 float &y() { return vec[1]; }
00225 float &z() { return vec[2]; }
00226 float &w() { return vec[3]; }
00227
00228 fpreal x() const { return vec[0]; }
00229 fpreal y() const { return vec[1]; }
00230 fpreal z() const { return vec[2]; }
00231 fpreal w() const { return vec[3]; }
00232
00233 void save(ostream &os, int binary=0) const;
00234 bool load(UT_IStream &is);
00235
00236 protected:
00237 void initialize(fpreal qx = 0, fpreal qy = 0,
00238 fpreal qz = 0, fpreal qw = 0)
00239 {
00240 vec[0] = qx; vec[1] = qy;
00241 vec[2] = qz; vec[3] = qw;
00242 }
00243 private:
00244
00245 friend ostream &operator<<(ostream &os, const UT_Quaternion &v)
00246 {
00247 v.save(os);
00248 return os;
00249 }
00250 float vec[4];
00251 };
00252
00253 inline UT_Quaternion
00254 operator*(const UT_Quaternion &q1, const UT_Quaternion &q2)
00255 {
00256 UT_Quaternion product = q1;
00257
00258 product *= q2;
00259
00260 return UT_Quaternion(product);
00261 }
00262
00263 inline UT_Quaternion
00264 operator+(const UT_Quaternion &q1, const UT_Quaternion &q2)
00265 {
00266 return UT_Quaternion(q1.vec[0] + q2.vec[0],
00267 q1.vec[1] + q2.vec[1],
00268 q1.vec[2] + q2.vec[2],
00269 q1.vec[3] + q2.vec[3]);
00270 }
00271
00272 inline UT_Quaternion
00273 operator-(const UT_Quaternion &q1, const UT_Quaternion &q2)
00274 {
00275 return UT_Quaternion(q1.vec[0] - q2.vec[0],
00276 q1.vec[1] - q2.vec[1],
00277 q1.vec[2] - q2.vec[2],
00278 q1.vec[3] - q2.vec[3]);
00279 }
00280
00281 inline UT_Quaternion
00282 operator-(const UT_Quaternion &q)
00283 {
00284 return UT_Quaternion(-q.vec[0],
00285 -q.vec[1],
00286 -q.vec[2],
00287 -q.vec[3]);
00288 }
00289
00290 inline UT_Quaternion
00291 operator*(const UT_Quaternion &q, fpreal scalar)
00292 {
00293 return UT_Quaternion(q.vec[0] * scalar,
00294 q.vec[1] * scalar,
00295 q.vec[2] * scalar,
00296 q.vec[3] * scalar);
00297 }
00298
00299 inline UT_Quaternion
00300 operator*(fpreal scalar, const UT_Quaternion &q)
00301 {
00302 return UT_Quaternion(q.vec[0] * scalar,
00303 q.vec[1] * scalar,
00304 q.vec[2] * scalar,
00305 q.vec[3] * scalar);
00306 }
00307
00308 inline UT_Quaternion
00309 operator/(const UT_Quaternion &a, const UT_Quaternion &b)
00310 {
00311 UT_Quaternion a1 = a;
00312 UT_Quaternion b1 = b;
00313
00314 b1.invert();
00315 a1 *= b1;
00316
00317 return UT_Quaternion(a1);
00318 }
00319
00320 inline UT_Quaternion
00321 operator/(const UT_Quaternion &q, fpreal scalar)
00322 {
00323 fpreal d = 1.0F/scalar;
00324 return UT_Quaternion(q.vec[0]*d, q.vec[1]*d, q.vec[2]*d, q.vec[3]*d);
00325 }
00326
00327 inline fpreal
00328 dot( const UT_Quaternion &q1, const UT_Quaternion &q2 )
00329 {
00330 return q1.x()*q2.x() + q1.y()*q2.y() + q1.z()*q2.z() + q1.w()*q2.w();
00331 }
00332
00333 #endif