OSG  3.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Quat.h
Go to the documentation of this file.
1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2  *
3  * This library is open source and may be redistributed and/or modified under
4  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5  * (at your option) any later version. The full license is in LICENSE file
6  * included with this distribution, and on the openscenegraph.org website.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * OpenSceneGraph Public License for more details.
12 */
13 
14 #ifndef OSG_QUAT
15 #define OSG_QUAT 1
16 
17 #include <osg/Export>
18 #include <osg/Vec3f>
19 #include <osg/Vec4f>
20 #include <osg/Vec3d>
21 #include <osg/Vec4d>
22 
23 namespace osg {
24 
25 class Matrixf;
26 class Matrixd;
27 
30 {
31 
32  public:
33 
34  typedef double value_type;
35 
36  value_type _v[4]; // a four-vector
37 
38  inline Quat() { _v[0]=0.0; _v[1]=0.0; _v[2]=0.0; _v[3]=1.0; }
39 
40  inline Quat( value_type x, value_type y, value_type z, value_type w )
41  {
42  _v[0]=x;
43  _v[1]=y;
44  _v[2]=z;
45  _v[3]=w;
46  }
47 
48  inline Quat( const Vec4f& v )
49  {
50  _v[0]=v.x();
51  _v[1]=v.y();
52  _v[2]=v.z();
53  _v[3]=v.w();
54  }
55 
56  inline Quat( const Vec4d& v )
57  {
58  _v[0]=v.x();
59  _v[1]=v.y();
60  _v[2]=v.z();
61  _v[3]=v.w();
62  }
63 
64  inline Quat( value_type angle, const Vec3f& axis)
65  {
66  makeRotate(angle,axis);
67  }
68  inline Quat( value_type angle, const Vec3d& axis)
69  {
70  makeRotate(angle,axis);
71  }
72 
73  inline Quat( value_type angle1, const Vec3f& axis1,
74  value_type angle2, const Vec3f& axis2,
75  value_type angle3, const Vec3f& axis3)
76  {
77  makeRotate(angle1,axis1,angle2,axis2,angle3,axis3);
78  }
79 
80  inline Quat( value_type angle1, const Vec3d& axis1,
81  value_type angle2, const Vec3d& axis2,
82  value_type angle3, const Vec3d& axis3)
83  {
84  makeRotate(angle1,axis1,angle2,axis2,angle3,axis3);
85  }
86 
87  inline Quat& operator = (const Quat& v) { _v[0]=v._v[0]; _v[1]=v._v[1]; _v[2]=v._v[2]; _v[3]=v._v[3]; return *this; }
88 
89  inline bool operator == (const Quat& v) const { return _v[0]==v._v[0] && _v[1]==v._v[1] && _v[2]==v._v[2] && _v[3]==v._v[3]; }
90 
91  inline bool operator != (const Quat& v) const { return _v[0]!=v._v[0] || _v[1]!=v._v[1] || _v[2]!=v._v[2] || _v[3]!=v._v[3]; }
92 
93  inline bool operator < (const Quat& v) const
94  {
95  if (_v[0]<v._v[0]) return true;
96  else if (_v[0]>v._v[0]) return false;
97  else if (_v[1]<v._v[1]) return true;
98  else if (_v[1]>v._v[1]) return false;
99  else if (_v[2]<v._v[2]) return true;
100  else if (_v[2]>v._v[2]) return false;
101  else return (_v[3]<v._v[3]);
102  }
103 
104  /* ----------------------------------
105  Methods to access data members
106  ---------------------------------- */
107 
108  inline Vec4d asVec4() const
109  {
110  return Vec4d(_v[0], _v[1], _v[2], _v[3]);
111  }
112 
113  inline Vec3d asVec3() const
114  {
115  return Vec3d(_v[0], _v[1], _v[2]);
116  }
117 
118  inline void set(value_type x, value_type y, value_type z, value_type w)
119  {
120  _v[0]=x;
121  _v[1]=y;
122  _v[2]=z;
123  _v[3]=w;
124  }
125 
126  inline void set(const osg::Vec4f& v)
127  {
128  _v[0]=v.x();
129  _v[1]=v.y();
130  _v[2]=v.z();
131  _v[3]=v.w();
132  }
133 
134  inline void set(const osg::Vec4d& v)
135  {
136  _v[0]=v.x();
137  _v[1]=v.y();
138  _v[2]=v.z();
139  _v[3]=v.w();
140  }
141 
142  void set(const Matrixf& matrix);
143 
144  void set(const Matrixd& matrix);
145 
146  void get(Matrixf& matrix) const;
147 
148  void get(Matrixd& matrix) const;
149 
150 
151  inline value_type & operator [] (int i) { return _v[i]; }
152  inline value_type operator [] (int i) const { return _v[i]; }
153 
154  inline value_type & x() { return _v[0]; }
155  inline value_type & y() { return _v[1]; }
156  inline value_type & z() { return _v[2]; }
157  inline value_type & w() { return _v[3]; }
158 
159  inline value_type x() const { return _v[0]; }
160  inline value_type y() const { return _v[1]; }
161  inline value_type z() const { return _v[2]; }
162  inline value_type w() const { return _v[3]; }
163 
165  bool zeroRotation() const { return _v[0]==0.0 && _v[1]==0.0 && _v[2]==0.0 && _v[3]==1.0; }
166 
167 
168  /* -------------------------------------------------------------
169  BASIC ARITHMETIC METHODS
170  Implemented in terms of Vec4s. Some Vec4 operators, e.g.
171  operator* are not appropriate for quaternions (as
172  mathematical objects) so they are implemented differently.
173  Also define methods for conjugate and the multiplicative inverse.
174  ------------------------------------------------------------- */
176  inline const Quat operator * (value_type rhs) const
177  {
178  return Quat(_v[0]*rhs, _v[1]*rhs, _v[2]*rhs, _v[3]*rhs);
179  }
180 
182  inline Quat& operator *= (value_type rhs)
183  {
184  _v[0]*=rhs;
185  _v[1]*=rhs;
186  _v[2]*=rhs;
187  _v[3]*=rhs;
188  return *this; // enable nesting
189  }
190 
192  inline const Quat operator*(const Quat& rhs) const
193  {
194  return Quat( rhs._v[3]*_v[0] + rhs._v[0]*_v[3] + rhs._v[1]*_v[2] - rhs._v[2]*_v[1],
195  rhs._v[3]*_v[1] - rhs._v[0]*_v[2] + rhs._v[1]*_v[3] + rhs._v[2]*_v[0],
196  rhs._v[3]*_v[2] + rhs._v[0]*_v[1] - rhs._v[1]*_v[0] + rhs._v[2]*_v[3],
197  rhs._v[3]*_v[3] - rhs._v[0]*_v[0] - rhs._v[1]*_v[1] - rhs._v[2]*_v[2] );
198  }
199 
201  inline Quat& operator*=(const Quat& rhs)
202  {
203  value_type x = rhs._v[3]*_v[0] + rhs._v[0]*_v[3] + rhs._v[1]*_v[2] - rhs._v[2]*_v[1];
204  value_type y = rhs._v[3]*_v[1] - rhs._v[0]*_v[2] + rhs._v[1]*_v[3] + rhs._v[2]*_v[0];
205  value_type z = rhs._v[3]*_v[2] + rhs._v[0]*_v[1] - rhs._v[1]*_v[0] + rhs._v[2]*_v[3];
206  _v[3] = rhs._v[3]*_v[3] - rhs._v[0]*_v[0] - rhs._v[1]*_v[1] - rhs._v[2]*_v[2];
207 
208  _v[2] = z;
209  _v[1] = y;
210  _v[0] = x;
211 
212  return (*this); // enable nesting
213  }
214 
216  inline Quat operator / (value_type rhs) const
217  {
218  value_type div = 1.0/rhs;
219  return Quat(_v[0]*div, _v[1]*div, _v[2]*div, _v[3]*div);
220  }
221 
223  inline Quat& operator /= (value_type rhs)
224  {
225  value_type div = 1.0/rhs;
226  _v[0]*=div;
227  _v[1]*=div;
228  _v[2]*=div;
229  _v[3]*=div;
230  return *this;
231  }
232 
234  inline const Quat operator/(const Quat& denom) const
235  {
236  return ( (*this) * denom.inverse() );
237  }
238 
240  inline Quat& operator/=(const Quat& denom)
241  {
242  (*this) = (*this) * denom.inverse();
243  return (*this); // enable nesting
244  }
245 
247  inline const Quat operator + (const Quat& rhs) const
248  {
249  return Quat(_v[0]+rhs._v[0], _v[1]+rhs._v[1],
250  _v[2]+rhs._v[2], _v[3]+rhs._v[3]);
251  }
252 
254  inline Quat& operator += (const Quat& rhs)
255  {
256  _v[0] += rhs._v[0];
257  _v[1] += rhs._v[1];
258  _v[2] += rhs._v[2];
259  _v[3] += rhs._v[3];
260  return *this; // enable nesting
261  }
262 
264  inline const Quat operator - (const Quat& rhs) const
265  {
266  return Quat(_v[0]-rhs._v[0], _v[1]-rhs._v[1],
267  _v[2]-rhs._v[2], _v[3]-rhs._v[3] );
268  }
269 
271  inline Quat& operator -= (const Quat& rhs)
272  {
273  _v[0]-=rhs._v[0];
274  _v[1]-=rhs._v[1];
275  _v[2]-=rhs._v[2];
276  _v[3]-=rhs._v[3];
277  return *this; // enable nesting
278  }
279 
282  inline const Quat operator - () const
283  {
284  return Quat (-_v[0], -_v[1], -_v[2], -_v[3]);
285  }
286 
288  value_type length() const
289  {
290  return sqrt( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3]);
291  }
292 
294  value_type length2() const
295  {
296  return _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3];
297  }
298 
300  inline Quat conj () const
301  {
302  return Quat( -_v[0], -_v[1], -_v[2], _v[3] );
303  }
304 
306  inline const Quat inverse () const
307  {
308  return conj() / length2();
309  }
310 
311  /* --------------------------------------------------------
312  METHODS RELATED TO ROTATIONS
313  Set a quaternion which will perform a rotation of an
314  angle around the axis given by the vector (x,y,z).
315  Should be written to also accept an angle and a Vec3?
316 
317  Define Spherical Linear interpolation method also
318 
319  Not inlined - see the Quat.cpp file for implementation
320  -------------------------------------------------------- */
321  void makeRotate( value_type angle,
322  value_type x, value_type y, value_type z );
323  void makeRotate ( value_type angle, const Vec3f& vec );
324  void makeRotate ( value_type angle, const Vec3d& vec );
325 
326  void makeRotate ( value_type angle1, const Vec3f& axis1,
327  value_type angle2, const Vec3f& axis2,
328  value_type angle3, const Vec3f& axis3);
329  void makeRotate ( value_type angle1, const Vec3d& axis1,
330  value_type angle2, const Vec3d& axis2,
331  value_type angle3, const Vec3d& axis3);
332 
338  void makeRotate( const Vec3f& vec1, const Vec3f& vec2 );
344  void makeRotate( const Vec3d& vec1, const Vec3d& vec2 );
345 
346  void makeRotate_original( const Vec3d& vec1, const Vec3d& vec2 );
347 
349  void getRotate ( value_type & angle, value_type & x, value_type & y, value_type & z ) const;
350 
352  void getRotate ( value_type & angle, Vec3f& vec ) const;
353 
355  void getRotate ( value_type & angle, Vec3d& vec ) const;
356 
359  void slerp ( value_type t, const Quat& from, const Quat& to);
360 
362  Vec3f operator* (const Vec3f& v) const
363  {
364  // nVidia SDK implementation
365  Vec3f uv, uuv;
366  Vec3f qvec(_v[0], _v[1], _v[2]);
367  uv = qvec ^ v;
368  uuv = qvec ^ uv;
369  uv *= ( 2.0f * _v[3] );
370  uuv *= 2.0f;
371  return v + uv + uuv;
372  }
373 
375  Vec3d operator* (const Vec3d& v) const
376  {
377  // nVidia SDK implementation
378  Vec3d uv, uuv;
379  Vec3d qvec(_v[0], _v[1], _v[2]);
380  uv = qvec ^ v;
381  uuv = qvec ^ uv;
382  uv *= ( 2.0f * _v[3] );
383  uuv *= 2.0f;
384  return v + uv + uuv;
385  }
386 
387  protected:
388 
389 }; // end of class prototype
390 
391 } // end of namespace
392 
393 #endif
Quat(value_type angle1, const Vec3f &axis1, value_type angle2, const Vec3f &axis2, value_type angle3, const Vec3f &axis3)
Definition: Quat.h:73
#define OSG_EXPORT
Definition: Export.h:43
value_type x() const
Definition: Quat.h:159
bool zeroRotation() const
Definition: Quat.h:165
value_type & y()
Definition: Quat.h:155
value_type & y()
Definition: Vec4d.h:91
const Quat inverse() const
Multiplicative inverse method: q^(-1) = q^*/(q.q^*)
Definition: Quat.h:306
double value_type
Definition: Quat.h:34
Vec4d asVec4() const
Definition: Quat.h:108
Quat(value_type angle1, const Vec3d &axis1, value_type angle2, const Vec3d &axis2, value_type angle3, const Vec3d &axis3)
Definition: Quat.h:80
Quat(const Vec4f &v)
Definition: Quat.h:48
value_type & x()
Definition: Vec4d.h:90
Quat(value_type angle, const Vec3f &axis)
Definition: Quat.h:64
value_type & x()
Definition: Quat.h:154
value_type & y()
Definition: Vec4f.h:88
value_type z() const
Definition: Quat.h:161
void set(const osg::Vec4d &v)
Definition: Quat.h:134
value_type length2() const
Length of the quaternion = vec . vec.
Definition: Quat.h:294
value_type & z()
Definition: Vec4d.h:92
const Quat operator/(const Quat &denom) const
Binary divide.
Definition: Quat.h:234
Quat()
Definition: Quat.h:38
value_type & z()
Definition: Quat.h:156
Quat(value_type x, value_type y, value_type z, value_type w)
Definition: Quat.h:40
value_type length() const
Length of the quaternion = sqrt( vec . vec )
Definition: Quat.h:288
const Quat operator*(const Quat &rhs) const
Binary multiply.
Definition: Quat.h:192
void set(value_type x, value_type y, value_type z, value_type w)
Definition: Quat.h:118
Vec3f operator*(const Vec3f &v, const Matrixd &m)
Definition: Matrixd.h:787
value_type & w()
Definition: Vec4f.h:90
Definition: AlphaFunc.h:19
Vec3d asVec3() const
Definition: Quat.h:113
Quat(const Vec4d &v)
Definition: Quat.h:56
void set(const osg::Vec4f &v)
Definition: Quat.h:126
value_type & w()
Definition: Vec4d.h:93
Quat & operator/=(const Quat &denom)
Unary divide.
Definition: Quat.h:240
value_type & z()
Definition: Vec4f.h:89
value_type w() const
Definition: Quat.h:162
value_type & x()
Definition: Vec4f.h:87
Definition: Quat.h:29
value_type _v[4]
Definition: Quat.h:36
value_type y() const
Definition: Quat.h:160
value_type & w()
Definition: Quat.h:157
Quat conj() const
Conjugate.
Definition: Quat.h:300
Quat & operator*=(const Quat &rhs)
Unary multiply.
Definition: Quat.h:201
Quat(value_type angle, const Vec3d &axis)
Definition: Quat.h:68