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