HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Quat.h
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
29 ///////////////////////////////////////////////////////////////////////////
30 
31 #ifndef OPENVDB_MATH_QUAT_H_HAS_BEEN_INCLUDED
32 #define OPENVDB_MATH_QUAT_H_HAS_BEEN_INCLUDED
33 
34 #include "Mat.h"
35 #include "Mat3.h"
36 #include "Math.h"
37 #include "Vec3.h"
38 #include <openvdb/Exceptions.h>
39 #include <cmath>
40 #include <iostream>
41 #include <sstream>
42 #include <string>
43 
44 
45 namespace openvdb {
47 namespace OPENVDB_VERSION_NAME {
48 namespace math {
49 
50 template<typename T> class Quat;
51 
52 /// Linear interpolation between the two quaternions
53 template <typename T>
54 Quat<T> slerp(const Quat<T> &q1, const Quat<T> &q2, T t, T tolerance=0.00001)
55 {
56  T qdot, angle, sineAngle;
57 
58  qdot = q1.dot(q2);
59 
60  if (fabs(qdot) >= 1.0) {
61  angle = 0; // not necessary but suppresses compiler warning
62  sineAngle = 0;
63  } else {
64  angle = acos(qdot);
65  sineAngle = sin(angle);
66  }
67 
68  //
69  // Denominator close to 0 corresponds to the case where the
70  // two quaternions are close to the same rotation. In this
71  // case linear interpolation is used but we normalize to
72  // guarantee unit length
73  //
74  if (sineAngle <= tolerance) {
75  T s = 1.0 - t;
76 
77  Quat<T> qtemp(s * q1[0] + t * q2[0], s * q1[1] + t * q2[1],
78  s * q1[2] + t * q2[2], s * q1[3] + t * q2[3]);
79  //
80  // Check the case where two close to antipodal quaternions were
81  // blended resulting in a nearly zero result which can happen,
82  // for example, if t is close to 0.5. In this case it is not safe
83  // to project back onto the sphere.
84  //
85  double lengthSquared = qtemp.dot(qtemp);
86 
87  if (lengthSquared <= tolerance * tolerance) {
88  qtemp = (t < 0.5) ? q1 : q2;
89  } else {
90  qtemp *= 1.0 / sqrt(lengthSquared);
91  }
92  return qtemp;
93  } else {
94 
95  T sine = 1.0 / sineAngle;
96  T a = sin((1.0 - t) * angle) * sine;
97  T b = sin(t * angle) * sine;
98  return Quat<T>(a * q1[0] + b * q2[0], a * q1[1] + b * q2[1],
99  a * q1[2] + b * q2[2], a * q1[3] + b * q2[3]);
100  }
101 
102 }
103 
104 template<typename T>
105 class Quat
106 {
107 public:
108  using value_type = T;
109  using ValueType = T;
110  static const int size = 4;
111 
112  /// Trivial constructor, the quaternion is NOT initialized
113  Quat() {}
114 
115  /// Constructor with four arguments, e.g. Quatf q(1,2,3,4);
116  Quat(T x, T y, T z, T w)
117  {
118  mm[0] = x;
119  mm[1] = y;
120  mm[2] = z;
121  mm[3] = w;
122 
123  }
124 
125  /// Constructor with array argument, e.g. float a[4]; Quatf q(a);
126  Quat(T *a)
127  {
128  mm[0] = a[0];
129  mm[1] = a[1];
130  mm[2] = a[2];
131  mm[3] = a[3];
132 
133  }
134 
135  /// Constructor given rotation as axis and angle, the axis must be
136  /// unit vector
137  Quat(const Vec3<T> &axis, T angle)
138  {
139  // assert( REL_EQ(axis.length(), 1.) );
140 
141  T s = T(sin(angle*T(0.5)));
142 
143  mm[0] = axis.x() * s;
144  mm[1] = axis.y() * s;
145  mm[2] = axis.z() * s;
146 
147  mm[3] = T(cos(angle*T(0.5)));
148 
149  }
150 
151  /// Constructor given rotation as axis and angle
153  {
154  T s = T(sin(angle*T(0.5)));
155 
156  mm[0] = (axis==math::X_AXIS) * s;
157  mm[1] = (axis==math::Y_AXIS) * s;
158  mm[2] = (axis==math::Z_AXIS) * s;
159 
160  mm[3] = T(cos(angle*T(0.5)));
161  }
162 
163  /// Constructor given a rotation matrix
164  template<typename T1>
165  Quat(const Mat3<T1> &rot) {
166 
167  // verify that the matrix is really a rotation
168  if(!isUnitary(rot)) { // unitary is reflection or rotation
169  OPENVDB_THROW(ArithmeticError,
170  "A non-rotation matrix can not be used to construct a quaternion");
171  }
172  if (!isApproxEqual(rot.det(), T1(1))) { // rule out reflection
173  OPENVDB_THROW(ArithmeticError,
174  "A reflection matrix can not be used to construct a quaternion");
175  }
176 
177  T trace(rot.trace());
178  if (trace > 0) {
179 
180  T q_w = 0.5 * std::sqrt(trace+1);
181  T factor = 0.25 / q_w;
182 
183  mm[0] = factor * (rot(1,2) - rot(2,1));
184  mm[1] = factor * (rot(2,0) - rot(0,2));
185  mm[2] = factor * (rot(0,1) - rot(1,0));
186  mm[3] = q_w;
187  } else if (rot(0,0) > rot(1,1) && rot(0,0) > rot(2,2)) {
188 
189  T q_x = 0.5 * sqrt(rot(0,0)- rot(1,1)-rot(2,2)+1);
190  T factor = 0.25 / q_x;
191 
192  mm[0] = q_x;
193  mm[1] = factor * (rot(0,1) + rot(1,0));
194  mm[2] = factor * (rot(2,0) + rot(0,2));
195  mm[3] = factor * (rot(1,2) - rot(2,1));
196  } else if (rot(1,1) > rot(2,2)) {
197 
198  T q_y = 0.5 * sqrt(rot(1,1)-rot(0,0)-rot(2,2)+1);
199  T factor = 0.25 / q_y;
200 
201  mm[0] = factor * (rot(0,1) + rot(1,0));
202  mm[1] = q_y;
203  mm[2] = factor * (rot(1,2) + rot(2,1));
204  mm[3] = factor * (rot(2,0) - rot(0,2));
205  } else {
206 
207  T q_z = 0.5 * sqrt(rot(2,2)-rot(0,0)-rot(1,1)+1);
208  T factor = 0.25 / q_z;
209 
210  mm[0] = factor * (rot(2,0) + rot(0,2));
211  mm[1] = factor * (rot(1,2) + rot(2,1));
212  mm[2] = q_z;
213  mm[3] = factor * (rot(0,1) - rot(1,0));
214  }
215  }
216 
217  /// Copy constructor
218  Quat(const Quat &q)
219  {
220  mm[0] = q.mm[0];
221  mm[1] = q.mm[1];
222  mm[2] = q.mm[2];
223  mm[3] = q.mm[3];
224 
225  }
226 
227  /// Reference to the component, e.g. q.x() = 4.5f;
228  T& x() { return mm[0]; }
229  T& y() { return mm[1]; }
230  T& z() { return mm[2]; }
231  T& w() { return mm[3]; }
232 
233  /// Get the component, e.g. float f = q.w();
234  T x() const { return mm[0]; }
235  T y() const { return mm[1]; }
236  T z() const { return mm[2]; }
237  T w() const { return mm[3]; }
238 
239  // Number of elements
240  static unsigned numElements() { return 4; }
241 
242  /// Array style reference to the components, e.g. q[3] = 1.34f;
243  T& operator[](int i) { return mm[i]; }
244 
245  /// Array style constant reference to the components, e.g. float f = q[1];
246  T operator[](int i) const { return mm[i]; }
247 
248  /// Cast to T*
249  operator T*() { return mm; }
250  operator const T*() const { return mm; }
251 
252  /// Alternative indexed reference to the elements
253  T& operator()(int i) { return mm[i]; }
254 
255  /// Alternative indexed constant reference to the elements,
256  T operator()(int i) const { return mm[i]; }
257 
258  /// Return angle of rotation
259  T angle() const
260  {
261  T sqrLength = mm[0]*mm[0] + mm[1]*mm[1] + mm[2]*mm[2];
262 
263  if ( sqrLength > 1.0e-8 ) {
264 
265  return T(T(2.0) * acos(mm[3]));
266 
267  } else {
268 
269  return T(0.0);
270  }
271  }
272 
273  /// Return axis of rotation
274  Vec3<T> axis() const
275  {
276  T sqrLength = mm[0]*mm[0] + mm[1]*mm[1] + mm[2]*mm[2];
277 
278  if ( sqrLength > 1.0e-8 ) {
279 
280  T invLength = T(T(1)/sqrt(sqrLength));
281 
282  return Vec3<T>( mm[0]*invLength, mm[1]*invLength, mm[2]*invLength );
283  } else {
284 
285  return Vec3<T>(1,0,0);
286  }
287  }
288 
289 
290  /// "this" quaternion gets initialized to [x, y, z, w]
291  Quat& init(T x, T y, T z, T w)
292  {
293  mm[0] = x; mm[1] = y; mm[2] = z; mm[3] = w;
294  return *this;
295  }
296 
297  /// "this" quaternion gets initialized to identity, same as setIdentity()
298  Quat& init() { return setIdentity(); }
299 
300  /// Set "this" quaternion to rotation specified by axis and angle,
301  /// the axis must be unit vector
303  {
304 
305  T s = T(sin(angle*T(0.5)));
306 
307  mm[0] = axis.x() * s;
308  mm[1] = axis.y() * s;
309  mm[2] = axis.z() * s;
310 
311  mm[3] = T(cos(angle*T(0.5)));
312 
313  return *this;
314  } // axisAngleTest
315 
316  /// Set "this" vector to zero
318  {
319  mm[0] = mm[1] = mm[2] = mm[3] = 0;
320  return *this;
321  }
322 
323  /// Set "this" vector to identity
325  {
326  mm[0] = mm[1] = mm[2] = 0;
327  mm[3] = 1;
328  return *this;
329  }
330 
331  /// Returns vector of x,y,z rotational components
332  Vec3<T> eulerAngles(RotationOrder rotationOrder) const
333  { return math::eulerAngles(Mat3<T>(*this), rotationOrder); }
334 
335  /// Assignment operator
336  Quat& operator=(const Quat &q)
337  {
338  mm[0] = q.mm[0];
339  mm[1] = q.mm[1];
340  mm[2] = q.mm[2];
341  mm[3] = q.mm[3];
342 
343  return *this;
344  }
345 
346  /// Equality operator, does exact floating point comparisons
347  bool operator==(const Quat &q) const
348  {
349  return (isExactlyEqual(mm[0],q.mm[0]) &&
350  isExactlyEqual(mm[1],q.mm[1]) &&
351  isExactlyEqual(mm[2],q.mm[2]) &&
352  isExactlyEqual(mm[3],q.mm[3]) );
353  }
354 
355  /// Test if "this" is equivalent to q with tolerance of eps value
356  bool eq(const Quat &q, T eps=1.0e-7) const
357  {
358  return isApproxEqual(mm[0],q.mm[0],eps) && isApproxEqual(mm[1],q.mm[1],eps) &&
359  isApproxEqual(mm[2],q.mm[2],eps) && isApproxEqual(mm[3],q.mm[3],eps) ;
360  } // trivial
361 
362  /// Add quaternion q to "this" quaternion, e.g. q += q1;
364  {
365  mm[0] += q.mm[0];
366  mm[1] += q.mm[1];
367  mm[2] += q.mm[2];
368  mm[3] += q.mm[3];
369 
370  return *this;
371  }
372 
373  /// Subtract quaternion q from "this" quaternion, e.g. q -= q1;
375  {
376  mm[0] -= q.mm[0];
377  mm[1] -= q.mm[1];
378  mm[2] -= q.mm[2];
379  mm[3] -= q.mm[3];
380 
381  return *this;
382  }
383 
384  /// Scale "this" quaternion by scalar, e.g. q *= scalar;
385  Quat& operator*=(T scalar)
386  {
387  mm[0] *= scalar;
388  mm[1] *= scalar;
389  mm[2] *= scalar;
390  mm[3] *= scalar;
391 
392  return *this;
393  }
394 
395  /// Return (this+q), e.g. q = q1 + q2;
396  Quat operator+(const Quat &q) const
397  {
398  return Quat<T>(mm[0]+q.mm[0], mm[1]+q.mm[1], mm[2]+q.mm[2], mm[3]+q.mm[3]);
399  }
400 
401  /// Return (this-q), e.g. q = q1 - q2;
402  Quat operator-(const Quat &q) const
403  {
404  return Quat<T>(mm[0]-q.mm[0], mm[1]-q.mm[1], mm[2]-q.mm[2], mm[3]-q.mm[3]);
405  }
406 
407  /// Return (this*q), e.g. q = q1 * q2;
408  Quat operator*(const Quat &q) const
409  {
410  Quat<T> prod;
411 
412  prod.mm[0] = mm[3]*q.mm[0] + mm[0]*q.mm[3] + mm[1]*q.mm[2] - mm[2]*q.mm[1];
413  prod.mm[1] = mm[3]*q.mm[1] + mm[1]*q.mm[3] + mm[2]*q.mm[0] - mm[0]*q.mm[2];
414  prod.mm[2] = mm[3]*q.mm[2] + mm[2]*q.mm[3] + mm[0]*q.mm[1] - mm[1]*q.mm[0];
415  prod.mm[3] = mm[3]*q.mm[3] - mm[0]*q.mm[0] - mm[1]*q.mm[1] - mm[2]*q.mm[2];
416 
417  return prod;
418 
419  }
420 
421  /// Assigns this to (this*q), e.g. q *= q1;
423  {
424  *this = *this * q;
425  return *this;
426  }
427 
428  /// Return (this*scalar), e.g. q = q1 * scalar;
429  Quat operator*(T scalar) const
430  {
431  return Quat<T>(mm[0]*scalar, mm[1]*scalar, mm[2]*scalar, mm[3]*scalar);
432  }
433 
434  /// Return (this/scalar), e.g. q = q1 / scalar;
435  Quat operator/(T scalar) const
436  {
437  return Quat<T>(mm[0]/scalar, mm[1]/scalar, mm[2]/scalar, mm[3]/scalar);
438  }
439 
440  /// Negation operator, e.g. q = -q;
441  Quat operator-() const
442  { return Quat<T>(-mm[0], -mm[1], -mm[2], -mm[3]); }
443 
444  /// this = q1 + q2
445  /// "this", q1 and q2 need not be distinct objects, e.g. q.add(q1,q);
446  Quat& add(const Quat &q1, const Quat &q2)
447  {
448  mm[0] = q1.mm[0] + q2.mm[0];
449  mm[1] = q1.mm[1] + q2.mm[1];
450  mm[2] = q1.mm[2] + q2.mm[2];
451  mm[3] = q1.mm[3] + q2.mm[3];
452 
453  return *this;
454  }
455 
456  /// this = q1 - q2
457  /// "this", q1 and q2 need not be distinct objects, e.g. q.sub(q1,q);
458  Quat& sub(const Quat &q1, const Quat &q2)
459  {
460  mm[0] = q1.mm[0] - q2.mm[0];
461  mm[1] = q1.mm[1] - q2.mm[1];
462  mm[2] = q1.mm[2] - q2.mm[2];
463  mm[3] = q1.mm[3] - q2.mm[3];
464 
465  return *this;
466  }
467 
468  /// this = q1 * q2
469  /// q1 and q2 must be distinct objects than "this", e.g. q.mult(q1,q2);
470  Quat& mult(const Quat &q1, const Quat &q2)
471  {
472  mm[0] = q1.mm[3]*q2.mm[0] + q1.mm[0]*q2.mm[3] +
473  q1.mm[1]*q2.mm[2] - q1.mm[2]*q2.mm[1];
474  mm[1] = q1.mm[3]*q2.mm[1] + q1.mm[1]*q2.mm[3] +
475  q1.mm[2]*q2.mm[0] - q1.mm[0]*q2.mm[2];
476  mm[2] = q1.mm[3]*q2.mm[2] + q1.mm[2]*q2.mm[3] +
477  q1.mm[0]*q2.mm[1] - q1.mm[1]*q2.mm[0];
478  mm[3] = q1.mm[3]*q2.mm[3] - q1.mm[0]*q2.mm[0] -
479  q1.mm[1]*q2.mm[1] - q1.mm[2]*q2.mm[2];
480 
481  return *this;
482  }
483 
484  /// this = scalar*q, q need not be distinct object than "this",
485  /// e.g. q.scale(1.5,q1);
486  Quat& scale(T scale, const Quat &q)
487  {
488  mm[0] = scale * q.mm[0];
489  mm[1] = scale * q.mm[1];
490  mm[2] = scale * q.mm[2];
491  mm[3] = scale * q.mm[3];
492 
493  return *this;
494  }
495 
496  /// Dot product
497  T dot(const Quat &q) const
498  {
499  return (mm[0]*q.mm[0] + mm[1]*q.mm[1] + mm[2]*q.mm[2] + mm[3]*q.mm[3]);
500  }
501 
502  /// Return the quaternion rate corrsponding to the angular velocity omega
503  /// and "this" current rotation
504  Quat derivative(const Vec3<T>& omega) const
505  {
506  return Quat<T>( +w()*omega.x() -z()*omega.y() +y()*omega.z() ,
507  +z()*omega.x() +w()*omega.y() -x()*omega.z() ,
508  -y()*omega.x() +x()*omega.y() +w()*omega.z() ,
509  -x()*omega.x() -y()*omega.y() -z()*omega.z() );
510  }
511 
512  /// this = normalized this
513  bool normalize(T eps = T(1.0e-8))
514  {
515  T d = T(sqrt(mm[0]*mm[0] + mm[1]*mm[1] + mm[2]*mm[2] + mm[3]*mm[3]));
516  if( isApproxEqual(d, T(0.0), eps) ) return false;
517  *this *= ( T(1)/d );
518  return true;
519  }
520 
521  /// this = normalized this
522  Quat unit() const
523  {
524  T d = sqrt(mm[0]*mm[0] + mm[1]*mm[1] + mm[2]*mm[2] + mm[3]*mm[3]);
525  if( isExactlyEqual(d , T(0.0) ) )
526  OPENVDB_THROW(ArithmeticError,
527  "Normalizing degenerate quaternion");
528  return *this / d;
529  }
530 
531  /// returns inverse of this
532  Quat inverse(T tolerance = T(0))
533  {
534  T d = mm[0]*mm[0] + mm[1]*mm[1] + mm[2]*mm[2] + mm[3]*mm[3];
535  if( isApproxEqual(d, T(0.0), tolerance) )
536  OPENVDB_THROW(ArithmeticError,
537  "Cannot invert degenerate quaternion");
538  Quat result = *this/-d;
539  result.mm[3] = -result.mm[3];
540  return result;
541  }
542 
543 
544  /// Return the conjugate of "this", same as invert without
545  /// unit quaternion test
546  Quat conjugate() const
547  {
548  return Quat<T>(-mm[0], -mm[1], -mm[2], mm[3]);
549  }
550 
551  /// Return rotated vector by "this" quaternion
553  {
554  Mat3<T> m(*this);
555  return m.transform(v);
556  }
557 
558  /// Predefined constants, e.g. Quat q = Quat::identity();
559  static Quat zero() { return Quat<T>(0,0,0,0); }
560  static Quat identity() { return Quat<T>(0,0,0,1); }
561 
562  /// @return string representation of Classname
563  std::string str() const
564  {
565  std::ostringstream buffer;
566 
567  buffer << "[";
568 
569  // For each column
570  for (unsigned j(0); j < 4; j++) {
571  if (j) buffer << ", ";
572  buffer << mm[j];
573  }
574 
575  buffer << "]";
576 
577  return buffer.str();
578  }
579 
580  /// Output to the stream, e.g. std::cout << q << std::endl;
581  friend std::ostream& operator<<(std::ostream &stream, const Quat &q)
582  {
583  stream << q.str();
584  return stream;
585  }
586 
587  friend Quat slerp<>(const Quat &q1, const Quat &q2, T t, T tolerance);
588 
589  void write(std::ostream& os) const { os.write(static_cast<char*>(&mm), sizeof(T) * 4); }
590  void read(std::istream& is) { is.read(static_cast<char*>(&mm), sizeof(T) * 4); }
591 
592 protected:
593  T mm[4];
594 };
595 
596 /// Multiply each element of the given quaternion by @a scalar and return the result.
597 template <typename S, typename T>
598 Quat<T> operator*(S scalar, const Quat<T> &q) { return q*scalar; }
599 
600 
601 /// @brief Interpolate between m1 and m2.
602 /// Converts to quaternion form and uses slerp
603 /// m1 and m2 must be rotation matrices!
604 template <typename T, typename T0>
605 Mat3<T> slerp(const Mat3<T0> &m1, const Mat3<T0> &m2, T t)
606 {
607  using MatType = Mat3<T>;
608 
609  Quat<T> q1(m1);
610  Quat<T> q2(m2);
611 
612  if (q1.dot(q2) < 0) q2 *= -1;
613 
614  Quat<T> qslerp = slerp<T>(q1, q2, static_cast<T>(t));
615  MatType m = rotation<MatType>(qslerp);
616  return m;
617 }
618 
619 
620 
621 /// Interpolate between m1 and m4 by converting m1 ... m4 into
622 /// quaternions and treating them as control points of a Bezier
623 /// curve using slerp in place of lerp in the De Castlejeau evaluation
624 /// algorithm. Just like a cubic Bezier curve, this will interpolate
625 /// m1 at t = 0 and m4 at t = 1 but in general will not pass through
626 /// m2 and m3. Unlike a standard Bezier curve this curve will not have
627 /// the convex hull property.
628 /// m1 ... m4 must be rotation matrices!
629 template <typename T, typename T0>
630 Mat3<T> bezLerp(const Mat3<T0> &m1, const Mat3<T0> &m2,
631  const Mat3<T0> &m3, const Mat3<T0> &m4,
632  T t)
633 {
634  Mat3<T> m00, m01, m02, m10, m11;
635 
636  m00 = slerp(m1, m2, t);
637  m01 = slerp(m2, m3, t);
638  m02 = slerp(m3, m4, t);
639 
640  m10 = slerp(m00, m01, t);
641  m11 = slerp(m01, m02, t);
642 
643  return slerp(m10, m11, t);
644 }
645 
648 
649 } // namespace math
650 
651 
652 template<> inline math::Quats zeroVal<math::Quats >() { return math::Quats::zero(); }
653 template<> inline math::Quatd zeroVal<math::Quatd >() { return math::Quatd::zero(); }
654 
655 } // namespace OPENVDB_VERSION_NAME
656 } // namespace openvdb
657 
658 #endif //OPENVDB_MATH_QUAT_H_HAS_BEEN_INCLUDED
659 
660 // Copyright (c) DreamWorks Animation LLC
661 // All rights reserved. This software is distributed under the
662 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
GLdouble s
Definition: glew.h:1390
Quat operator*(T scalar) const
Return (this*scalar), e.g. q = q1 * scalar;.
Definition: Quat.h:429
SYS_API double cos(double x)
Definition: SYS_FPUMath.h:69
Quat(T x, T y, T z, T w)
Constructor with four arguments, e.g. Quatf q(1,2,3,4);.
Definition: Quat.h:116
Vec3< T > axis() const
Return axis of rotation.
Definition: Quat.h:274
GLsizeiptr size
Definition: glew.h:1681
GLuint GLuint stream
Definition: glew.h:7265
Quat & sub(const Quat &q1, const Quat &q2)
Definition: Quat.h:458
T operator[](int i) const
Array style constant reference to the components, e.g. float f = q[1];.
Definition: Quat.h:246
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:415
Quat derivative(const Vec3< T > &omega) const
Definition: Quat.h:504
Quat & scale(T scale, const Quat &q)
Definition: Quat.h:486
GLenum GLenum GLenum GLenum GLenum scale
Definition: glew.h:13880
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:9477
Quat operator*(const Quat &q) const
Return (this*q), e.g. q = q1 * q2;.
Definition: Quat.h:408
GA_API const UT_StringHolder rot
vfloat4 sqrt(const vfloat4 &a)
Definition: simd.h:7231
Mat3< typename promote< T0, T1 >::type > operator*(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Multiply m0 by m1 and return the resulting matrix.
Definition: Mat3.h:645
bool operator==(const Quat &q) const
Equality operator, does exact floating point comparisons.
Definition: Quat.h:347
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:200
Quat unit() const
this = normalized this
Definition: Quat.h:522
const GLdouble * m
Definition: glew.h:9124
const GLdouble * v
Definition: glew.h:1391
Quat & init(T x, T y, T z, T w)
"this" quaternion gets initialized to [x, y, z, w]
Definition: Quat.h:291
GLdouble angle
Definition: glew.h:9135
Quat & operator=(const Quat &q)
Assignment operator.
Definition: Quat.h:336
Vec3< typename MatType::value_type > eulerAngles(const MatType &mat, RotationOrder rotationOrder, typename MatType::value_type eps=static_cast< typename MatType::value_type >(1.0e-8))
Return the Euler angles composing the given rotation matrix.
Definition: Mat.h:365
Quat operator-(const Quat &q) const
Return (this-q), e.g. q = q1 - q2;.
Definition: Quat.h:402
GLdouble GLdouble z
Definition: glew.h:1559
Quat operator+(const Quat &q) const
Return (this+q), e.g. q = q1 + q2;.
Definition: Quat.h:396
Vec3< T0 > transform(const Vec3< T0 > &v) const
Definition: Mat3.h:553
Quat operator*=(const Quat &q)
Assigns this to (this*q), e.g. q *= q1;.
Definition: Quat.h:422
GLdouble GLdouble GLdouble GLdouble q
Definition: glew.h:1414
Quat operator/(T scalar) const
Return (this/scalar), e.g. q = q1 / scalar;.
Definition: Quat.h:435
Quat inverse(T tolerance=T(0))
returns inverse of this
Definition: Quat.h:532
Mat3< T > bezLerp(const Mat3< T0 > &m1, const Mat3< T0 > &m2, const Mat3< T0 > &m3, const Mat3< T0 > &m4, T t)
Definition: Quat.h:630
Quat(T *a)
Constructor with array argument, e.g. float a[4]; Quatf q(a);.
Definition: Quat.h:126
Quat(const Mat3< T1 > &rot)
Constructor given a rotation matrix.
Definition: Quat.h:165
Quat & operator-=(const Quat &q)
Subtract quaternion q from "this" quaternion, e.g. q -= q1;.
Definition: Quat.h:374
bool eq(const Quat &q, T eps=1.0e-7) const
Test if "this" is equivalent to q with tolerance of eps value.
Definition: Quat.h:356
GLint GLint GLint GLint GLint x
Definition: glew.h:1252
void read(std::istream &is)
Definition: Quat.h:590
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1252
Quat(math::Axis axis, T angle)
Constructor given rotation as axis and angle.
Definition: Quat.h:152
GLuint buffer
Definition: glew.h:1680
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
bool normalize(T eps=T(1.0e-8))
this = normalized this
Definition: Quat.h:513
Vec3< T > rotateVector(const Vec3< T > &v) const
Return rotated vector by "this" quaternion.
Definition: Quat.h:552
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1890
Quat(const Quat &q)
Copy constructor.
Definition: Quat.h:218
T angle(const Vec2< T > &v1, const Vec2< T > &v2)
Definition: Vec2.h:472
bool isUnitary(const MatType &m)
Determine if a matrix is unitary (i.e., rotation or reflection).
Definition: Mat.h:921
Quat operator-() const
Negation operator, e.g. q = -q;.
Definition: Quat.h:441
Vec3< T > eulerAngles(RotationOrder rotationOrder) const
Returns vector of x,y,z rotational components.
Definition: Quat.h:332
T det() const
Determinant of matrix.
Definition: Mat3.h:527
SYS_API double acos(double x)
Definition: SYS_FPUMath.h:83
Quat & setIdentity()
Set "this" vector to identity.
Definition: Quat.h:324
Quat()
Trivial constructor, the quaternion is NOT initialized.
Definition: Quat.h:113
bool isApproxEqual(const Type &a, const Type &b)
Return true if a is equal to b to within the default floating-point comparison tolerance.
Definition: Math.h:378
GLdouble GLdouble GLdouble b
Definition: glew.h:9122
Quat & init()
"this" quaternion gets initialized to identity, same as setIdentity()
Definition: Quat.h:298
GLsizei const GLchar *const * string
Definition: glew.h:1844
T dot(const Quat &q) const
Dot product.
Definition: Quat.h:497
T & operator()(int i)
Alternative indexed reference to the elements.
Definition: Quat.h:253
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:110
T & operator[](int i)
Array style reference to the components, e.g. q[3] = 1.34f;.
Definition: Quat.h:243
T trace() const
Trace of matrix.
Definition: Mat3.h:536
T & x()
Reference to the component, e.g. q.x() = 4.5f;.
Definition: Quat.h:228
T angle() const
Return angle of rotation.
Definition: Quat.h:259
void write(std::ostream &os) const
Definition: Quat.h:589
Quat & setAxisAngle(const Vec3< T > &axis, T angle)
Definition: Quat.h:302
T x() const
Get the component, e.g. float f = q.w();.
Definition: Quat.h:234
GLuint64EXT * result
Definition: glew.h:14007
Quat & operator*=(T scalar)
Scale "this" quaternion by scalar, e.g. q *= scalar;.
Definition: Quat.h:385
Quat & add(const Quat &q1, const Quat &q2)
Definition: Quat.h:446
Quat< T > slerp(const Quat< T > &q1, const Quat< T > &q2, T t, T tolerance=0.00001)
Linear interpolation between the two quaternions.
Definition: Quat.h:54
static Quat zero()
Predefined constants, e.g. Quat q = Quat::identity();.
Definition: Quat.h:559
Quat & mult(const Quat &q1, const Quat &q2)
Definition: Quat.h:470
Quat & setZero()
Set "this" vector to zero.
Definition: Quat.h:317
Quat(const Vec3< T > &axis, T angle)
Definition: Quat.h:137
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:146
GLdouble GLdouble t
Definition: glew.h:1398
SYS_API double sin(double x)
Definition: SYS_FPUMath.h:71
Quat & operator+=(const Quat &q)
Add quaternion q to "this" quaternion, e.g. q += q1;.
Definition: Quat.h:363
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
T operator()(int i) const
Alternative indexed constant reference to the elements,.
Definition: Quat.h:256
friend std::ostream & operator<<(std::ostream &stream, const Quat &q)
Output to the stream, e.g. std::cout << q << std::endl;.
Definition: Quat.h:581