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