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