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 _BASE_QUAT4_
00026 #define _BASE_QUAT4_
00027
00028 #include <iostream>
00029
00030 #include <base/base>
00031 #include <base/consts>
00032 #include <base/Object>
00033 #include <base/Vector3>
00034 #include <base/Vector4>
00035 #include <base/Point3>
00036 #include <base/Point4>
00037 #include <base/Matrix4>
00038
00039
00040 namespace base {
00041
00042 class Quat4;
00043 class Serializer;
00044 inline Quat4 inverse(const Quat4& q);
00045
00046
00047
00048
00049
00050
00051 class Quat4
00052 {
00053
00054 public:
00055 Quat4() { setIdentity(); }
00056 Quat4(const Quat4& q) { this->operator=(q); }
00057 Quat4(const Vector3& v) : v(v), w(Real(1)) {}
00058 Quat4(const Vector4& v) : v(v.x,v.y,v.z), w(v.w) {}
00059 explicit Quat4(const Real& s) : v(Real(0),Real(0),Real(0)), w(s) {}
00060 Quat4(Real x, Real y, Real z, Real w) : v(x,y,z), w(w) {}
00061 Quat4(const Vector3& axis, Real angle) { setRotation(axis,angle); }
00062 ~Quat4() {}
00063
00064 static const Int X = 1;
00065 static const Int Y = 2;
00066 static const Int Z = 3;
00067 static const Int W = 4;
00068
00069 void setIdentity() throw()
00070 {
00071 v.x=v.y=v.z=Real(0); w=Real(1);
00072 }
00073
00074 void setZero() throw()
00075 {
00076 setIdentity(); w=Real(0);
00077 }
00078
00079
00080 Real& e(Int i) throw()
00081 {
00082 #ifdef DEBUG
00083 if ((i < 1) || (i > 4))
00084 throw std::runtime_error(Exception("quaternion index out of bounds (debug only check)"));
00085 #endif
00086 return (i<4)?v.e(i):w;
00087 }
00088
00089 const Real& e(Int i) const throw()
00090 {
00091 #ifdef DEBUG
00092 if ((i < 1) || (i > 4))
00093 throw std::runtime_error(Exception("quaternion index out of bounds (debug only check)"));
00094 #endif
00095 return (i<4)?v.e(i):w;
00096 }
00097
00098 Real& at(Int i) throw(std::out_of_range)
00099 {
00100 if ((i < 1) || (i > 4))
00101 throw std::out_of_range(Exception("quaternion index out of bounds"));
00102
00103 return (i<4)?v.e(i):w;
00104 }
00105
00106 const Real& at(Int i) const throw(std::out_of_range)
00107 {
00108 if ((i < 1) || (i > 4))
00109 throw std::out_of_range(Exception("quaternion index out of bounds"));
00110
00111 return (i<3)?v.e(i):w;
00112 }
00113
00114 Real& operator[](Int i)
00115 { return e(i); }
00116
00117 const Real& operator[](Int i) const
00118 { return e(i); }
00119
00120 Quat4& operator=(const Quat4& src) throw()
00121 {
00122 if (&src != this) {
00123 v=src.v; w=src.w;
00124 }
00125 return *this;
00126 }
00127
00128 bool operator==(const Quat4& q) const throw()
00129 {
00130 if (&q == this) return true;
00131
00132 return ((v==q.v)&&(w==q.w));
00133 }
00134
00135 bool equals(const Quat4& q) const throw()
00136 {
00137 if (&q == this) return true;
00138
00139 return (v.equals(q.v) && (base::equals(w,q.w)));
00140 }
00141
00142 Real norm() const throw()
00143 { return v.x*v.x+v.y*v.y+v.z*v.z+w*w; }
00144
00145 Quat4& normalize() throw()
00146 {
00147 Real n = norm();
00148
00149 if ((!base::equals(n,1)) && (n>0)) {
00150 Real l = base::sqrt(n);
00151 v /= l;
00152 w /= l;
00153 }
00154 return *this;
00155 }
00156
00157 Quat4& conjugate() { v.negate(); return *this; }
00158
00159 Quat4& invert() throw()
00160 {
00161 Real n;
00162 if (base::equals(n=norm(),1))
00163 conjugate();
00164 else {
00165 conjugate();
00166 if (n>0)
00167 *this /= n;
00168 }
00169 return *this;
00170 }
00171
00172 Quat4& operator*=(const Quat4& qr);
00173 Quat4& operator*=(Real s) { v*=s; w*=s; return *this; }
00174 Quat4& operator/=(Real s) { v/=s; w/=s; return *this; }
00175 Quat4& operator+=(const Quat4& q) { v+=q.v; w+=q.w; return *this; }
00176 Quat4& operator-=(const Quat4& q) { v-=q.v; w-=q.w; return *this; }
00177
00178 Quat4& negate() throw() { v.negate(); w=-w; return *this; }
00179
00180
00181 void setRotation(const Matrix4& rotation);
00182
00183 void setRotation(const Vector3& axis, Real angle);
00184 void getRotation(Vector3& axis, Real& angle) const;
00185 void rotatePoint(Point4& p) const;
00186 void rotatePoint(Point3& p) const
00187 { Point4 p4(p); p4.w=0; rotatePoint(p4); p=Point3(p4.x,p4.y,p4.z); }
00188 Point3 rotate(const Point3& p) const
00189 { Point4 ret(p); rotatePoint(ret); return Point3(ret.x,ret.y,ret.z); }
00190 Point4 rotate(const Point4& p) const
00191 { Point4 ret(p); rotatePoint(ret); return ret; }
00192
00193 static Quat4 interpolate(const Quat4& from, const Quat4& to, Real t);
00194 static Real angleBetween(const Quat4& q1, const Quat4& q2);
00195
00196 operator Matrix4() const;
00197
00198 Real* c_array() { return &v.x; }
00199
00200 void serialize(Serializer& s);
00201
00202 Vector3 v;
00203 Real w;
00204
00205 friend std::ostream& operator<<(std::ostream&, const Quat4&);
00206
00207 };
00208
00209
00210
00211
00212
00213 inline Quat4 operator*(const Quat4& q1, const Quat4& q2)
00214 { Quat4 r(q1); return (r *= q2); }
00215
00216 inline Quat4 operator+(const Quat4& q1, const Quat4& q2)
00217 { Quat4 r(q1); return (r += q2); }
00218
00219 inline Quat4 operator-(const Quat4& q1, const Quat4& q2)
00220 { Quat4 r(q1); return (r += q2); }
00221
00222 inline Quat4 operator-(const Quat4& q1)
00223 { Quat4 r(q1); return r.negate(); }
00224
00225 inline Quat4 operator*(const Quat4& q1, const Real& s)
00226 { Quat4 r(q1); return (r *= s); }
00227
00228 inline Quat4 operator*(const Real& s, const Quat4& q1)
00229 { Quat4 r(q1); return (r *= s); }
00230
00231 inline Quat4 operator/(const Quat4& q1, const Real& s)
00232 { Quat4 r(q1); return (r /= s); }
00233
00234 inline Quat4 inverse(const Quat4& q)
00235 { Quat4 r(q); return r.invert(); }
00236
00237 inline Quat4 conjugate(const Quat4& q)
00238 { Quat4 r(q); return r.conjugate(); }
00239
00240
00241 std::ostream& operator<<(std::ostream& out, const Quat4& q);
00242
00243
00244 }
00245
00246 #endif
00247