OpenVDB: Mat4.h Source File

OpenVDB 3.1.0

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

Mat4.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2015 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 //
30
31 #ifndef OPENVDB_MATH_MAT4_H_HAS_BEEN_INCLUDED
32 #define OPENVDB_MATH_MAT4_H_HAS_BEEN_INCLUDED
33
34 #include <openvdb/Exceptions.h>
35 #include <openvdb/Platform.h>
36 #include <iomanip>
37 #include <assert.h>
38 #include <math.h>
39 #include <algorithm>
40 #include "Math.h"
41 #include "Mat3.h"
42 #include "Vec3.h"
43 #include "Vec4.h"
44
45
46 namespace openvdb {
47 OPENVDB_USE_VERSION_NAMESPACE
48 namespace OPENVDB_VERSION_NAME {
49 namespace math {
50
51 template<typename T> class Vec4;
52
53
56 template<typename T>
57 class Mat4: public Mat<4, T>
58 {
59 public:
61 typedef T value_type;
62 typedef T ValueType;
63 typedef Mat<4, T> MyBase;
64
66 Mat4() {}
67
69
75 template<typename Source>
76 Mat4(Source *a)
77 {
78 for (int i = 0; i < 16; i++) {
79 MyBase::mm[i] = a[i];
80 }
81 }
82
84
90 template<typename Source>
91 Mat4(Source a, Source b, Source c, Source d,
92 Source e, Source f, Source g, Source h,
93 Source i, Source j, Source k, Source l,
94 Source m, Source n, Source o, Source p)
95 {
96 MyBase::mm[ 0] = T(a);
97 MyBase::mm[ 1] = T(b);
98 MyBase::mm[ 2] = T(c);
99 MyBase::mm[ 3] = T(d);
100
101 MyBase::mm[ 4] = T(e);
102 MyBase::mm[ 5] = T(f);
103 MyBase::mm[ 6] = T(g);
104 MyBase::mm[ 7] = T(h);
105
106 MyBase::mm[ 8] = T(i);
107 MyBase::mm[ 9] = T(j);
108 MyBase::mm[10] = T(k);
109 MyBase::mm[11] = T(l);
110
111 MyBase::mm[12] = T(m);
112 MyBase::mm[13] = T(n);
113 MyBase::mm[14] = T(o);
114 MyBase::mm[15] = T(p);
115 }
116
118 template<typename Source>
119 Mat4(const Vec4<Source> &v1, const Vec4<Source> &v2,
120 const Vec4<Source> &v3, const Vec4<Source> &v4)
121 {
122 setBasis(v1, v2, v3, v4);
123 }
124
126 Mat4(const Mat<4, T> &m)
127 {
128 for (int i = 0; i < 4; ++i) {
129 for (int j = 0; j < 4; ++j) {
130 MyBase::mm[i*4 + j] = m[i][j];
131 }
132 }
133 }
134
136 template<typename Source>
137 explicit Mat4(const Mat4<Source> &m)
138 {
139 const Source *src = m.asPointer();
140
141 for (int i=0; i<16; ++i) {
142 MyBase::mm[i] = static_cast<T>(src[i]);
143 }
144 }
145
147 static const Mat4<T>& identity() {
148 return sIdentity;
149 }
150
152 static const Mat4<T>& zero() {
153 return sZero;
154 }
155
157 void setRow(int i, const Vec4<T> &v)
158 {
159 // assert(i>=0 && i<4);
160 int i4 = i * 4;
161 MyBase::mm[i4+0] = v[0];
162 MyBase::mm[i4+1] = v[1];
163 MyBase::mm[i4+2] = v[2];
164 MyBase::mm[i4+3] = v[3];
165 }
166
168 Vec4<T> row(int i) const
169 {
170 // assert(i>=0 && i<3);
171 return Vec4<T>((*this)(i,0), (*this)(i,1), (*this)(i,2), (*this)(i,3));
172 }
173
175 void setCol(int j, const Vec4<T>& v)
176 {
177 // assert(j>=0 && j<4);
178 MyBase::mm[ 0+j] = v[0];
179 MyBase::mm[ 4+j] = v[1];
180 MyBase::mm[ 8+j] = v[2];
181 MyBase::mm[12+j] = v[3];
182 }
183
185 Vec4<T> col(int j) const
186 {
187 // assert(j>=0 && j<4);
188 return Vec4<T>((*this)(0,j), (*this)(1,j), (*this)(2,j), (*this)(3,j));
189 }
190
192 T* operator[](int i) { return &(MyBase::mm[i<<2]); }
195 const T* operator[](int i) const { return &(MyBase::mm[i<<2]); }
197
199 T* asPointer() {return MyBase::mm;}
200 const T* asPointer() const {return MyBase::mm;}
201
205 T& operator()(int i, int j)
206 {
207 // assert(i>=0 && i<4);
208 // assert(j>=0 && j<4);
209 return MyBase::mm[4*i+j];
210 }
211
215 T operator()(int i, int j) const
216 {
217 // assert(i>=0 && i<4);
218 // assert(j>=0 && j<4);
219 return MyBase::mm[4*i+j];
220 }
221
223 void setBasis(const Vec4<T> &v1, const Vec4<T> &v2,
224 const Vec4<T> &v3, const Vec4<T> &v4)
225 {
226 MyBase::mm[ 0] = v1[0];
227 MyBase::mm[ 1] = v1[1];
228 MyBase::mm[ 2] = v1[2];
229 MyBase::mm[ 3] = v1[3];
230
231 MyBase::mm[ 4] = v2[0];
232 MyBase::mm[ 5] = v2[1];
233 MyBase::mm[ 6] = v2[2];
234 MyBase::mm[ 7] = v2[3];
235
236 MyBase::mm[ 8] = v3[0];
237 MyBase::mm[ 9] = v3[1];
238 MyBase::mm[10] = v3[2];
239 MyBase::mm[11] = v3[3];
240
241 MyBase::mm[12] = v4[0];
242 MyBase::mm[13] = v4[1];
243 MyBase::mm[14] = v4[2];
244 MyBase::mm[15] = v4[3];
245 }
246
247
248 // Set "this" matrix to zero
249 void setZero()
250 {
251 MyBase::mm[ 0] = 0;
252 MyBase::mm[ 1] = 0;
253 MyBase::mm[ 2] = 0;
254 MyBase::mm[ 3] = 0;
255 MyBase::mm[ 4] = 0;
256 MyBase::mm[ 5] = 0;
257 MyBase::mm[ 6] = 0;
258 MyBase::mm[ 7] = 0;
259 MyBase::mm[ 8] = 0;
260 MyBase::mm[ 9] = 0;
261 MyBase::mm[10] = 0;
262 MyBase::mm[11] = 0;
263 MyBase::mm[12] = 0;
264 MyBase::mm[13] = 0;
265 MyBase::mm[14] = 0;
266 MyBase::mm[15] = 0;
267 }
268
270 void setIdentity()
271 {
272 MyBase::mm[ 0] = 1;
273 MyBase::mm[ 1] = 0;
274 MyBase::mm[ 2] = 0;
275 MyBase::mm[ 3] = 0;
276
277 MyBase::mm[ 4] = 0;
278 MyBase::mm[ 5] = 1;
279 MyBase::mm[ 6] = 0;
280 MyBase::mm[ 7] = 0;
281
282 MyBase::mm[ 8] = 0;
283 MyBase::mm[ 9] = 0;
284 MyBase::mm[10] = 1;
285 MyBase::mm[11] = 0;
286
287 MyBase::mm[12] = 0;
288 MyBase::mm[13] = 0;
289 MyBase::mm[14] = 0;
290 MyBase::mm[15] = 1;
291 }
292
293
295 void setMat3(const Mat3<T> &m)
296 {
297 for (int i = 0; i < 3; i++)
298 for (int j=0; j < 3; j++)
299 MyBase::mm[i*4+j] = m[i][j];
300 }
301
302 Mat3<T> getMat3() const
303 {
304 Mat3<T> m;
305
306 for (int i = 0; i < 3; i++)
307 for (int j = 0; j < 3; j++)
308 m[i][j] = MyBase::mm[i*4+j];
309
310 return m;
311 }
312
314 Vec3<T> getTranslation() const
315 {
316 return Vec3<T>(MyBase::mm[12], MyBase::mm[13], MyBase::mm[14]);
317 }
318
319 void setTranslation(const Vec3<T> &t)
320 {
321 MyBase::mm[12] = t[0];
322 MyBase::mm[13] = t[1];
323 MyBase::mm[14] = t[2];
324 }
325
327 template<typename Source>
328 const Mat4& operator=(const Mat4<Source> &m)
329 {
330 const Source *src = m.asPointer();
331
332 // don't suppress warnings when assigning from different numerical types
333 std::copy(src, (src + this->numElements()), MyBase::mm);
334 return *this;
335 }
336
338 bool eq(const Mat4 &m, T eps=1.0e-8) const
339 {
340 for (int i = 0; i < 16; i++) {
341 if (!isApproxEqual(MyBase::mm[i], m.mm[i], eps))
342 return false;
343 }
344 return true;
345 }
346
348 Mat4<T> operator-() const
349 {
350 return Mat4<T>(
351 -MyBase::mm[ 0], -MyBase::mm[ 1], -MyBase::mm[ 2], -MyBase::mm[ 3],
352 -MyBase::mm[ 4], -MyBase::mm[ 5], -MyBase::mm[ 6], -MyBase::mm[ 7],
353 -MyBase::mm[ 8], -MyBase::mm[ 9], -MyBase::mm[10], -MyBase::mm[11],
354 -MyBase::mm[12], -MyBase::mm[13], -MyBase::mm[14], -MyBase::mm[15]
355 );
356 } // trivial
357
359 template <typename S>
360 const Mat4<T>& operator*=(S scalar)
361 {
362 MyBase::mm[ 0] *= scalar;
363 MyBase::mm[ 1] *= scalar;
364 MyBase::mm[ 2] *= scalar;
365 MyBase::mm[ 3] *= scalar;
366
367 MyBase::mm[ 4] *= scalar;
368 MyBase::mm[ 5] *= scalar;
369 MyBase::mm[ 6] *= scalar;
370 MyBase::mm[ 7] *= scalar;
371
372 MyBase::mm[ 8] *= scalar;
373 MyBase::mm[ 9] *= scalar;
374 MyBase::mm[10] *= scalar;
375 MyBase::mm[11] *= scalar;
376
377 MyBase::mm[12] *= scalar;
378 MyBase::mm[13] *= scalar;
379 MyBase::mm[14] *= scalar;
380 MyBase::mm[15] *= scalar;
381 return *this;
382 }
383
385 template <typename S>
386 const Mat4<T> &operator+=(const Mat4<S> &m1)
387 {
388 const S* s = m1.asPointer();
389
390 MyBase::mm[ 0] += s[ 0];
391 MyBase::mm[ 1] += s[ 1];
392 MyBase::mm[ 2] += s[ 2];
393 MyBase::mm[ 3] += s[ 3];
394
395 MyBase::mm[ 4] += s[ 4];
396 MyBase::mm[ 5] += s[ 5];
397 MyBase::mm[ 6] += s[ 6];
398 MyBase::mm[ 7] += s[ 7];
399
400 MyBase::mm[ 8] += s[ 8];
401 MyBase::mm[ 9] += s[ 9];
402 MyBase::mm[10] += s[10];
403 MyBase::mm[11] += s[11];
404
405 MyBase::mm[12] += s[12];
406 MyBase::mm[13] += s[13];
407 MyBase::mm[14] += s[14];
408 MyBase::mm[15] += s[15];
409
410 return *this;
411 }
412
414 template <typename S>
415 const Mat4<T> &operator-=(const Mat4<S> &m1)
416 {
417 const S* s = m1.asPointer();
418
419 MyBase::mm[ 0] -= s[ 0];
420 MyBase::mm[ 1] -= s[ 1];
421 MyBase::mm[ 2] -= s[ 2];
422 MyBase::mm[ 3] -= s[ 3];
423
424 MyBase::mm[ 4] -= s[ 4];
425 MyBase::mm[ 5] -= s[ 5];
426 MyBase::mm[ 6] -= s[ 6];
427 MyBase::mm[ 7] -= s[ 7];
428
429 MyBase::mm[ 8] -= s[ 8];
430 MyBase::mm[ 9] -= s[ 9];
431 MyBase::mm[10] -= s[10];
432 MyBase::mm[11] -= s[11];
433
434 MyBase::mm[12] -= s[12];
435 MyBase::mm[13] -= s[13];
436 MyBase::mm[14] -= s[14];
437 MyBase::mm[15] -= s[15];
438
439 return *this;
440 }
441
443 template <typename S>
444 const Mat4<T> &operator*=(const Mat4<S> &m1)
445 {
446 Mat4<T> m0(*this);
447
448 const T* s0 = m0.asPointer();
449 const S* s1 = m1.asPointer();
450
451 for (int i = 0; i < 4; i++) {
452 int i4 = 4 * i;
453 MyBase::mm[i4+0] = static_cast<T>(s0[i4+0] * s1[ 0] +
454 s0[i4+1] * s1[ 4] +
455 s0[i4+2] * s1[ 8] +
456 s0[i4+3] * s1[12]);
457
458 MyBase::mm[i4+1] = static_cast<T>(s0[i4+0] * s1[ 1] +
459 s0[i4+1] * s1[ 5] +
460 s0[i4+2] * s1[ 9] +
461 s0[i4+3] * s1[13]);
462
463 MyBase::mm[i4+2] = static_cast<T>(s0[i4+0] * s1[ 2] +
464 s0[i4+1] * s1[ 6] +
465 s0[i4+2] * s1[10] +
466 s0[i4+3] * s1[14]);
467
468 MyBase::mm[i4+3] = static_cast<T>(s0[i4+0] * s1[ 3] +
469 s0[i4+1] * s1[ 7] +
470 s0[i4+2] * s1[11] +
471 s0[i4+3] * s1[15]);
472 }
473 return *this;
474 }
475
477 Mat4 transpose() const
478 {
479 return Mat4<T>(
480 MyBase::mm[ 0], MyBase::mm[ 4], MyBase::mm[ 8], MyBase::mm[12],
481 MyBase::mm[ 1], MyBase::mm[ 5], MyBase::mm[ 9], MyBase::mm[13],
482 MyBase::mm[ 2], MyBase::mm[ 6], MyBase::mm[10], MyBase::mm[14],
483 MyBase::mm[ 3], MyBase::mm[ 7], MyBase::mm[11], MyBase::mm[15]
484 );
485 }
486
487
490 Mat4 inverse(T tolerance = 0) const
491 {
492 //
493 // inv [ A | b ] = [ E | f ] A: 3x3, b: 3x1, c': 1x3 d: 1x1
494 // [ c' | d ] [ g' | h ]
495 //
496 // If A is invertible use
497 //
498 // E = A^-1 + p*h*r
499 // p = A^-1 * b
500 // f = -p * h
501 // g' = -h * c'
502 // h = 1 / (d - c'*p)
503 // r' = c'*A^-1
504 //
505 // Otherwise use gauss-jordan elimination
506 //
507
508 //
509 // We create this alias to ourself so we can easily use own subscript
510 // operator.
511 const Mat4<T>& m(*this);
512
513 T m0011 = m[0][0] * m[1][1];
514 T m0012 = m[0][0] * m[1][2];
515 T m0110 = m[0][1] * m[1][0];
516 T m0210 = m[0][2] * m[1][0];
517 T m0120 = m[0][1] * m[2][0];
518 T m0220 = m[0][2] * m[2][0];
519
520 T detA = m0011 * m[2][2] - m0012 * m[2][1] - m0110 * m[2][2]
521 + m0210 * m[2][1] + m0120 * m[1][2] - m0220 * m[1][1];
522
523 bool hasPerspective =
524 (!isExactlyEqual(m[0][3], T(0.0)) ||
525 !isExactlyEqual(m[1][3], T(0.0)) ||
526 !isExactlyEqual(m[2][3], T(0.0)) ||
527 !isExactlyEqual(m[3][3], T(1.0)));
528
529 T det;
530 if (hasPerspective) {
531 det = m[0][3] * det3(m, 1,2,3, 0,2,1)
532 + m[1][3] * det3(m, 2,0,3, 0,2,1)
533 + m[2][3] * det3(m, 3,0,1, 0,2,1)
534 + m[3][3] * detA;
535 } else {
536 det = detA * m[3][3];
537 }
538
539 Mat4<T> inv;
540 bool invertible;
541
542 if (isApproxEqual(det,T(0.0),tolerance)) {
543 invertible = false;
544
545 } else if (isApproxEqual(detA,T(0.0),T(1e-8))) {
546 // det is too small to rely on inversion by subblocks
547 invertible = m.invert(inv, tolerance);
548
549 } else {
550 invertible = true;
551 detA = 1.0 / detA;
552
553 //
554 // Calculate A^-1
555 //
556 inv[0][0] = detA * ( m[1][1] * m[2][2] - m[1][2] * m[2][1]);
557 inv[0][1] = detA * (-m[0][1] * m[2][2] + m[0][2] * m[2][1]);
558 inv[0][2] = detA * ( m[0][1] * m[1][2] - m[0][2] * m[1][1]);
559
560 inv[1][0] = detA * (-m[1][0] * m[2][2] + m[1][2] * m[2][0]);
561 inv[1][1] = detA * ( m[0][0] * m[2][2] - m0220);
562 inv[1][2] = detA * ( m0210 - m0012);
563
564 inv[2][0] = detA * ( m[1][0] * m[2][1] - m[1][1] * m[2][0]);
565 inv[2][1] = detA * ( m0120 - m[0][0] * m[2][1]);
566 inv[2][2] = detA * ( m0011 - m0110);
567
568 if (hasPerspective) {
569 //
570 // Calculate r, p, and h
571 //
572 Vec3<T> r;
573 r[0] = m[3][0] * inv[0][0] + m[3][1] * inv[1][0]
574 + m[3][2] * inv[2][0];
575 r[1] = m[3][0] * inv[0][1] + m[3][1] * inv[1][1]
576 + m[3][2] * inv[2][1];
577 r[2] = m[3][0] * inv[0][2] + m[3][1] * inv[1][2]
578 + m[3][2] * inv[2][2];
579
580 Vec3<T> p;
581 p[0] = inv[0][0] * m[0][3] + inv[0][1] * m[1][3]
582 + inv[0][2] * m[2][3];
583 p[1] = inv[1][0] * m[0][3] + inv[1][1] * m[1][3]
584 + inv[1][2] * m[2][3];
585 p[2] = inv[2][0] * m[0][3] + inv[2][1] * m[1][3]
586 + inv[2][2] * m[2][3];
587
588 T h = m[3][3] - p.dot(Vec3<T>(m[3][0],m[3][1],m[3][2]));
589 if (isApproxEqual(h,T(0.0),tolerance)) {
590 invertible = false;
591
592 } else {
593 h = 1.0 / h;
594
595 //
596 // Calculate h, g, and f
597 //
598 inv[3][3] = h;
599 inv[3][0] = -h * r[0];
600 inv[3][1] = -h * r[1];
601 inv[3][2] = -h * r[2];
602
603 inv[0][3] = -h * p[0];
604 inv[1][3] = -h * p[1];
605 inv[2][3] = -h * p[2];
606
607 //
608 // Calculate E
609 //
610 p *= h;
611 inv[0][0] += p[0] * r[0];
612 inv[0][1] += p[0] * r[1];
613 inv[0][2] += p[0] * r[2];
614 inv[1][0] += p[1] * r[0];
615 inv[1][1] += p[1] * r[1];
616 inv[1][2] += p[1] * r[2];
617 inv[2][0] += p[2] * r[0];
618 inv[2][1] += p[2] * r[1];
619 inv[2][2] += p[2] * r[2];
620 }
621 } else {
622 // Equations are much simpler in the non-perspective case
623 inv[3][0] = - (m[3][0] * inv[0][0] + m[3][1] * inv[1][0]
624 + m[3][2] * inv[2][0]);
625 inv[3][1] = - (m[3][0] * inv[0][1] + m[3][1] * inv[1][1]
626 + m[3][2] * inv[2][1]);
627 inv[3][2] = - (m[3][0] * inv[0][2] + m[3][1] * inv[1][2]
628 + m[3][2] * inv[2][2]);
629 inv[0][3] = 0.0;
630 inv[1][3] = 0.0;
631 inv[2][3] = 0.0;
632 inv[3][3] = 1.0;
633 }
634 }
635
636 if (!invertible) OPENVDB_THROW(ArithmeticError, "Inversion of singular 4x4 matrix");
637 return inv;
638 }
639
640
642 T det() const
643 {
644 const T *ap;
645 Mat3<T> submat;
646 T det;
647 T *sp;
648 int i, j, k, sign;
649
650 det = 0;
651 sign = 1;
652 for (i = 0; i < 4; i++) {
653 ap = &MyBase::mm[ 0];
654 sp = submat.asPointer();
655 for (j = 0; j < 4; j++) {
656 for (k = 0; k < 4; k++) {
657 if ((k != i) && (j != 0)) {
658 *sp++ = *ap;
659 }
660 ap++;
661 }
662 }
663
664 det += sign * MyBase::mm[i] * submat.det();
665 sign = -sign;
666 }
667
668 return det;
669 }
670
675 Mat4 snapBasis(Axis axis, const Vec3<T> &direction)
676 {return snapBasis(*this, axis, direction);}
677
679 static Mat4 translation(const Vec3d& v)
680 {
681 return Mat4(
682 T(1), T(0), T(0), T(0),
683 T(0), T(1), T(0), T(0),
684 T(0), T(0), T(1), T(0),
685 T(v.x()), T(v.y()),T(v.z()), T(1));
686 }
687
689 template <typename T0>
690 void setToTranslation(const Vec3<T0>& v)
691 {
692 MyBase::mm[ 0] = 1;
693 MyBase::mm[ 1] = 0;
694 MyBase::mm[ 2] = 0;
695 MyBase::mm[ 3] = 0;
696
697 MyBase::mm[ 4] = 0;
698 MyBase::mm[ 5] = 1;
699 MyBase::mm[ 6] = 0;
700 MyBase::mm[ 7] = 0;
701
702 MyBase::mm[ 8] = 0;
703 MyBase::mm[ 9] = 0;
704 MyBase::mm[10] = 1;
705 MyBase::mm[11] = 0;
706
707 MyBase::mm[12] = v.x();
708 MyBase::mm[13] = v.y();
709 MyBase::mm[14] = v.z();
710 MyBase::mm[15] = 1;
711 }
712
714 template <typename T0>
715 void preTranslate(const Vec3<T0>& tr)
716 {
717 Vec3<T> tmp(tr.x(), tr.y(), tr.z());
718 Mat4<T> Tr = Mat4<T>::translation(tmp);
719
720 *this = Tr * (*this);
721
722 }
723
725 template <typename T0>
726 void postTranslate(const Vec3<T0>& tr)
727 {
728 Vec3<T> tmp(tr.x(), tr.y(), tr.z());
729 Mat4<T> Tr = Mat4<T>::translation(tmp);
730
731 *this = (*this) * Tr;
732
733 }
734
735
737 template <typename T0>
738 void setToScale(const Vec3<T0>& v)
739 {
740 this->setIdentity();
741 MyBase::mm[ 0] = v.x();
742 MyBase::mm[ 5] = v.y();
743 MyBase::mm[10] = v.z();
744 }
745
746 // Left multiples by the specified scale matrix, i.e. Sc * (*this)
747 template <typename T0>
748 void preScale(const Vec3<T0>& v)
749 {
750 MyBase::mm[ 0] *= v.x();
751 MyBase::mm[ 1] *= v.x();
752 MyBase::mm[ 2] *= v.x();
753 MyBase::mm[ 3] *= v.x();
754
755 MyBase::mm[ 4] *= v.y();
756 MyBase::mm[ 5] *= v.y();
757 MyBase::mm[ 6] *= v.y();
758 MyBase::mm[ 7] *= v.y();
759
760 MyBase::mm[ 8] *= v.z();
761 MyBase::mm[ 9] *= v.z();
762 MyBase::mm[10] *= v.z();
763 MyBase::mm[11] *= v.z();
764 }
765
766
767
768 // Right multiples by the specified scale matrix, i.e. (*this) * Sc
769 template <typename T0>
770 void postScale(const Vec3<T0>& v)
771 {
772
773 MyBase::mm[ 0] *= v.x();
774 MyBase::mm[ 1] *= v.y();
775 MyBase::mm[ 2] *= v.z();
776
777 MyBase::mm[ 4] *= v.x();
778 MyBase::mm[ 5] *= v.y();
779 MyBase::mm[ 6] *= v.z();
780
781 MyBase::mm[ 8] *= v.x();
782 MyBase::mm[ 9] *= v.y();
783 MyBase::mm[10] *= v.z();
784
785 MyBase::mm[12] *= v.x();
786 MyBase::mm[13] *= v.y();
787 MyBase::mm[14] *= v.z();
788
789 }
790
791
795 void setToRotation(Axis axis, T angle) {*this = rotation<Mat4<T> >(axis, angle);}
796
800 void setToRotation(const Vec3<T>& axis, T angle) {*this = rotation<Mat4<T> >(axis, angle);}
801
804 void setToRotation(const Vec3<T>& v1, const Vec3<T>& v2) {*this = rotation<Mat4<T> >(v1, v2);}
805
806
810 void preRotate(Axis axis, T angle)
811 {
812 T c = static_cast<T>(cos(angle));
813 T s = -static_cast<T>(sin(angle)); // the "-" makes it clockwise
814
815 switch (axis) {
816 case X_AXIS:
817 {
818 T a4, a5, a6, a7;
819
820 a4 = c * MyBase::mm[ 4] - s * MyBase::mm[ 8];
821 a5 = c * MyBase::mm[ 5] - s * MyBase::mm[ 9];
822 a6 = c * MyBase::mm[ 6] - s * MyBase::mm[10];
823 a7 = c * MyBase::mm[ 7] - s * MyBase::mm[11];
824
825
826 MyBase::mm[ 8] = s * MyBase::mm[ 4] + c * MyBase::mm[ 8];
827 MyBase::mm[ 9] = s * MyBase::mm[ 5] + c * MyBase::mm[ 9];
828 MyBase::mm[10] = s * MyBase::mm[ 6] + c * MyBase::mm[10];
829 MyBase::mm[11] = s * MyBase::mm[ 7] + c * MyBase::mm[11];
830
831 MyBase::mm[ 4] = a4;
832 MyBase::mm[ 5] = a5;
833 MyBase::mm[ 6] = a6;
834 MyBase::mm[ 7] = a7;
835 }
836 break;
837
838 case Y_AXIS:
839 {
840 T a0, a1, a2, a3;
841
842 a0 = c * MyBase::mm[ 0] + s * MyBase::mm[ 8];
843 a1 = c * MyBase::mm[ 1] + s * MyBase::mm[ 9];
844 a2 = c * MyBase::mm[ 2] + s * MyBase::mm[10];
845 a3 = c * MyBase::mm[ 3] + s * MyBase::mm[11];
846
847 MyBase::mm[ 8] = -s * MyBase::mm[ 0] + c * MyBase::mm[ 8];
848 MyBase::mm[ 9] = -s * MyBase::mm[ 1] + c * MyBase::mm[ 9];
849 MyBase::mm[10] = -s * MyBase::mm[ 2] + c * MyBase::mm[10];
850 MyBase::mm[11] = -s * MyBase::mm[ 3] + c * MyBase::mm[11];
851
852
853 MyBase::mm[ 0] = a0;
854 MyBase::mm[ 1] = a1;
855 MyBase::mm[ 2] = a2;
856 MyBase::mm[ 3] = a3;
857 }
858 break;
859
860 case Z_AXIS:
861 {
862 T a0, a1, a2, a3;
863
864 a0 = c * MyBase::mm[ 0] - s * MyBase::mm[ 4];
865 a1 = c * MyBase::mm[ 1] - s * MyBase::mm[ 5];
866 a2 = c * MyBase::mm[ 2] - s * MyBase::mm[ 6];
867 a3 = c * MyBase::mm[ 3] - s * MyBase::mm[ 7];
868
869 MyBase::mm[ 4] = s * MyBase::mm[ 0] + c * MyBase::mm[ 4];
870 MyBase::mm[ 5] = s * MyBase::mm[ 1] + c * MyBase::mm[ 5];
871 MyBase::mm[ 6] = s * MyBase::mm[ 2] + c * MyBase::mm[ 6];
872 MyBase::mm[ 7] = s * MyBase::mm[ 3] + c * MyBase::mm[ 7];
873
874 MyBase::mm[ 0] = a0;
875 MyBase::mm[ 1] = a1;
876 MyBase::mm[ 2] = a2;
877 MyBase::mm[ 3] = a3;
878 }
879 break;
880
881 default:
882 assert(axis==X_AXIS || axis==Y_AXIS || axis==Z_AXIS);
883 }
884 }
885
886
890 void postRotate(Axis axis, T angle)
891 {
892 T c = static_cast<T>(cos(angle));
893 T s = -static_cast<T>(sin(angle)); // the "-" makes it clockwise
894
895
896
897 switch (axis) {
898 case X_AXIS:
899 {
900 T a2, a6, a10, a14;
901
902 a2 = c * MyBase::mm[ 2] - s * MyBase::mm[ 1];
903 a6 = c * MyBase::mm[ 6] - s * MyBase::mm[ 5];
904 a10 = c * MyBase::mm[10] - s * MyBase::mm[ 9];
905 a14 = c * MyBase::mm[14] - s * MyBase::mm[13];
906
907
908 MyBase::mm[ 1] = c * MyBase::mm[ 1] + s * MyBase::mm[ 2];
909 MyBase::mm[ 5] = c * MyBase::mm[ 5] + s * MyBase::mm[ 6];
910 MyBase::mm[ 9] = c * MyBase::mm[ 9] + s * MyBase::mm[10];
911 MyBase::mm[13] = c * MyBase::mm[13] + s * MyBase::mm[14];
912
913 MyBase::mm[ 2] = a2;
914 MyBase::mm[ 6] = a6;
915 MyBase::mm[10] = a10;
916 MyBase::mm[14] = a14;
917 }
918 break;
919
920 case Y_AXIS:
921 {
922 T a2, a6, a10, a14;
923
924 a2 = c * MyBase::mm[ 2] + s * MyBase::mm[ 0];
925 a6 = c * MyBase::mm[ 6] + s * MyBase::mm[ 4];
926 a10 = c * MyBase::mm[10] + s * MyBase::mm[ 8];
927 a14 = c * MyBase::mm[14] + s * MyBase::mm[12];
928
929 MyBase::mm[ 0] = c * MyBase::mm[ 0] - s * MyBase::mm[ 2];
930 MyBase::mm[ 4] = c * MyBase::mm[ 4] - s * MyBase::mm[ 6];
931 MyBase::mm[ 8] = c * MyBase::mm[ 8] - s * MyBase::mm[10];
932 MyBase::mm[12] = c * MyBase::mm[12] - s * MyBase::mm[14];
933
934 MyBase::mm[ 2] = a2;
935 MyBase::mm[ 6] = a6;
936 MyBase::mm[10] = a10;
937 MyBase::mm[14] = a14;
938 }
939 break;
940
941 case Z_AXIS:
942 {
943 T a1, a5, a9, a13;
944
945 a1 = c * MyBase::mm[ 1] - s * MyBase::mm[ 0];
946 a5 = c * MyBase::mm[ 5] - s * MyBase::mm[ 4];
947 a9 = c * MyBase::mm[ 9] - s * MyBase::mm[ 8];
948 a13 = c * MyBase::mm[13] - s * MyBase::mm[12];
949
950 MyBase::mm[ 0] = c * MyBase::mm[ 0] + s * MyBase::mm[ 1];
951 MyBase::mm[ 4] = c * MyBase::mm[ 4] + s * MyBase::mm[ 5];
952 MyBase::mm[ 8] = c * MyBase::mm[ 8] + s * MyBase::mm[ 9];
953 MyBase::mm[12] = c * MyBase::mm[12] + s * MyBase::mm[13];
954
955 MyBase::mm[ 1] = a1;
956 MyBase::mm[ 5] = a5;
957 MyBase::mm[ 9] = a9;
958 MyBase::mm[13] = a13;
959
960 }
961 break;
962
963 default:
964 assert(axis==X_AXIS || axis==Y_AXIS || axis==Z_AXIS);
965 }
966 }
967
972 void setToShear(Axis axis0, Axis axis1, T shearby)
973 {
974 *this = shear<Mat4<T> >(axis0, axis1, shearby);
975 }
976
977
980 void preShear(Axis axis0, Axis axis1, T shear)
981 {
982 int index0 = static_cast<int>(axis0);
983 int index1 = static_cast<int>(axis1);
984
985 // to row "index1" add a multiple of the index0 row
986 MyBase::mm[index1 * 4 + 0] += shear * MyBase::mm[index0 * 4 + 0];
987 MyBase::mm[index1 * 4 + 1] += shear * MyBase::mm[index0 * 4 + 1];
988 MyBase::mm[index1 * 4 + 2] += shear * MyBase::mm[index0 * 4 + 2];
989 MyBase::mm[index1 * 4 + 3] += shear * MyBase::mm[index0 * 4 + 3];
990 }
991
992
995 void postShear(Axis axis0, Axis axis1, T shear)
996 {
997 int index0 = static_cast<int>(axis0);
998 int index1 = static_cast<int>(axis1);
999
1000 // to collumn "index0" add a multiple of the index1 row
1001 MyBase::mm[index0 + 0] += shear * MyBase::mm[index1 + 0];
1002 MyBase::mm[index0 + 4] += shear * MyBase::mm[index1 + 4];
1003 MyBase::mm[index0 + 8] += shear * MyBase::mm[index1 + 8];
1004 MyBase::mm[index0 + 12] += shear * MyBase::mm[index1 + 12];
1005
1006 }
1007
1009 template<typename T0>
1010 Vec4<T0> transform(const Vec4<T0> &v) const
1011 {
1012 return static_cast< Vec4<T0> >(v * *this);
1013 }
1014
1016 template<typename T0>
1017 Vec3<T0> transform(const Vec3<T0> &v) const
1018 {
1019 return static_cast< Vec3<T0> >(v * *this);
1020 }
1021
1023 template<typename T0>
1024 Vec4<T0> pretransform(const Vec4<T0> &v) const
1025 {
1026 return static_cast< Vec4<T0> >(*this * v);
1027 }
1028
1030 template<typename T0>
1031 Vec3<T0> pretransform(const Vec3<T0> &v) const
1032 {
1033 return static_cast< Vec3<T0> >(*this * v);
1034 }
1035
1037 template<typename T0>
1038 Vec3<T0> transformH(const Vec3<T0> &p) const
1039 {
1040 T0 w;
1041
1042 // w = p * (*this).col(3);
1043 w = static_cast<T0>(p[0] * MyBase::mm[ 3] + p[1] * MyBase::mm[ 7]
1044 + p[2] * MyBase::mm[11] + MyBase::mm[15]);
1045
1046 if ( !isExactlyEqual(w , 0.0) ) {
1047 return Vec3<T0>(static_cast<T0>((p[0] * MyBase::mm[ 0] + p[1] * MyBase::mm[ 4] +
1048 p[2] * MyBase::mm[ 8] + MyBase::mm[12]) / w),
1049 static_cast<T0>((p[0] * MyBase::mm[ 1] + p[1] * MyBase::mm[ 5] +
1050 p[2] * MyBase::mm[ 9] + MyBase::mm[13]) / w),
1051 static_cast<T0>((p[0] * MyBase::mm[ 2] + p[1] * MyBase::mm[ 6] +
1052 p[2] * MyBase::mm[10] + MyBase::mm[14]) / w));
1053 }
1054
1055 return Vec3<T0>(0, 0, 0);
1056 }
1057
1059 template<typename T0>
1060 Vec3<T0> pretransformH(const Vec3<T0> &p) const
1061 {
1062 T0 w;
1063
1064 // w = p * (*this).col(3);
1065 w = p[0] * MyBase::mm[12] + p[1] * MyBase::mm[13] + p[2] * MyBase::mm[14] + MyBase::mm[15];
1066
1067 if ( !isExactlyEqual(w , 0.0) ) {
1068 return Vec3<T0>(static_cast<T0>((p[0] * MyBase::mm[ 0] + p[1] * MyBase::mm[ 1] +
1069 p[2] * MyBase::mm[ 2] + MyBase::mm[ 3]) / w),
1070 static_cast<T0>((p[0] * MyBase::mm[ 4] + p[1] * MyBase::mm[ 5] +
1071 p[2] * MyBase::mm[ 6] + MyBase::mm[ 7]) / w),
1072 static_cast<T0>((p[0] * MyBase::mm[ 8] + p[1] * MyBase::mm[ 9] +
1073 p[2] * MyBase::mm[10] + MyBase::mm[11]) / w));
1074 }
1075
1076 return Vec3<T0>(0, 0, 0);
1077 }
1078
1080 template<typename T0>
1081 Vec3<T0> transform3x3(const Vec3<T0> &v) const
1082 {
1083 return Vec3<T0>(
1084 static_cast<T0>(v[0] * MyBase::mm[ 0] + v[1] * MyBase::mm[ 4] + v[2] * MyBase::mm[ 8]),
1085 static_cast<T0>(v[0] * MyBase::mm[ 1] + v[1] * MyBase::mm[ 5] + v[2] * MyBase::mm[ 9]),
1086 static_cast<T0>(v[0] * MyBase::mm[ 2] + v[1] * MyBase::mm[ 6] + v[2] * MyBase::mm[10]));
1087 }
1088
1089
1090 private:
1091 bool invert(Mat4<T> &inverse, T tolerance) const;
1092
1093 T det2(const Mat4<T> &a, int i0, int i1, int j0, int j1) const {
1094 int i0row = i0 * 4;
1095 int i1row = i1 * 4;
1096 return a.mm[i0row+j0]*a.mm[i1row+j1] - a.mm[i0row+j1]*a.mm[i1row+j0];
1097 }
1098
1099 T det3(const Mat4<T> &a, int i0, int i1, int i2,
1100 int j0, int j1, int j2) const {
1101 int i0row = i0 * 4;
1102 return a.mm[i0row+j0]*det2(a, i1,i2, j1,j2) +
1103 a.mm[i0row+j1]*det2(a, i1,i2, j2,j0) +
1104 a.mm[i0row+j2]*det2(a, i1,i2, j0,j1);
1105 }
1106
1107 static const Mat4<T> sIdentity;
1108 static const Mat4<T> sZero;
1109 }; // class Mat4
1110
1111
1112 template <typename T>
1113 const Mat4<T> Mat4<T>::sIdentity = Mat4<T>(1, 0, 0, 0,
1114 0, 1, 0, 0,
1115 0, 0, 1, 0,
1116 0, 0, 0, 1);
1117
1118 template <typename T>
1119 const Mat4<T> Mat4<T>::sZero = Mat4<T>(0, 0, 0, 0,
1120 0, 0, 0, 0,
1121 0, 0, 0, 0,
1122 0, 0, 0, 0);
1123
1126 template <typename T0, typename T1>
1127 bool operator==(const Mat4<T0> &m0, const Mat4<T1> &m1)
1128 {
1129 const T0 *t0 = m0.asPointer();
1130 const T1 *t1 = m1.asPointer();
1131
1132 for (int i=0; i<16; ++i) if (!isExactlyEqual(t0[i], t1[i])) return false;
1133 return true;
1134 }
1135
1138 template <typename T0, typename T1>
1139 bool operator!=(const Mat4<T0> &m0, const Mat4<T1> &m1) { return !(m0 == m1); }
1140
1143 template <typename S, typename T>
1144 Mat4<typename promote<S, T>::type> operator*(S scalar, const Mat4<T> &m)
1145 {
1146 return m*scalar;
1147 }
1148
1151 template <typename S, typename T>
1152 Mat4<typename promote<S, T>::type> operator*(const Mat4<T> &m, S scalar)
1153 {
1154 Mat4<typename promote<S, T>::type> result(m);
1155 result *= scalar;
1156 return result;
1157 }
1158
1161 template<typename T, typename MT>
1162 inline Vec4<typename promote<T, MT>::type>
1163 operator*(const Mat4<MT> &_m,
1164 const Vec4<T> &_v)
1165 {
1166 MT const *m = _m.asPointer();
1167 return Vec4<typename promote<T, MT>::type>(
1168 _v[0]*m[0] + _v[1]*m[1] + _v[2]*m[2] + _v[3]*m[3],
1169 _v[0]*m[4] + _v[1]*m[5] + _v[2]*m[6] + _v[3]*m[7],
1170 _v[0]*m[8] + _v[1]*m[9] + _v[2]*m[10] + _v[3]*m[11],
1171 _v[0]*m[12] + _v[1]*m[13] + _v[2]*m[14] + _v[3]*m[15]);
1172 }
1173
1176 template<typename T, typename MT>
1177 inline Vec4<typename promote<T, MT>::type>
1178 operator*(const Vec4<T> &_v,
1179 const Mat4<MT> &_m)
1180 {
1181 MT const *m = _m.asPointer();
1182 return Vec4<typename promote<T, MT>::type>(
1183 _v[0]*m[0] + _v[1]*m[4] + _v[2]*m[8] + _v[3]*m[12],
1184 _v[0]*m[1] + _v[1]*m[5] + _v[2]*m[9] + _v[3]*m[13],
1185 _v[0]*m[2] + _v[1]*m[6] + _v[2]*m[10] + _v[3]*m[14],
1186 _v[0]*m[3] + _v[1]*m[7] + _v[2]*m[11] + _v[3]*m[15]);
1187 }
1188
1192 template<typename T, typename MT>
1193 inline Vec3<typename promote<T, MT>::type>
1194 operator*(const Mat4<MT> &_m,
1195 const Vec3<T> &_v)
1196 {
1197 MT const *m = _m.asPointer();
1198 return Vec3<typename promote<T, MT>::type>(
1199 _v[0]*m[0] + _v[1]*m[1] + _v[2]*m[2] + m[3],
1200 _v[0]*m[4] + _v[1]*m[5] + _v[2]*m[6] + m[7],
1201 _v[0]*m[8] + _v[1]*m[9] + _v[2]*m[10] + m[11]);
1202 }
1203
1207 template<typename T, typename MT>
1208 inline Vec3<typename promote<T, MT>::type>
1209 operator*(const Vec3<T> &_v,
1210 const Mat4<MT> &_m)
1211 {
1212 MT const *m = _m.asPointer();
1213 return Vec3<typename promote<T, MT>::type>(
1214 _v[0]*m[0] + _v[1]*m[4] + _v[2]*m[8] + m[12],
1215 _v[0]*m[1] + _v[1]*m[5] + _v[2]*m[9] + m[13],
1216 _v[0]*m[2] + _v[1]*m[6] + _v[2]*m[10] + m[14]);
1217 }
1218
1221 template <typename T0, typename T1>
1222 Mat4<typename promote<T0, T1>::type>
1223 operator+(const Mat4<T0> &m0, const Mat4<T1> &m1)
1224 {
1225 Mat4<typename promote<T0, T1>::type> result(m0);
1226 result += m1;
1227 return result;
1228 }
1229
1232 template <typename T0, typename T1>
1233 Mat4<typename promote<T0, T1>::type>
1234 operator-(const Mat4<T0> &m0, const Mat4<T1> &m1)
1235 {
1236 Mat4<typename promote<T0, T1>::type> result(m0);
1237 result -= m1;
1238 return result;
1239 }
1240
1244 template <typename T0, typename T1>
1245 Mat4<typename promote<T0, T1>::type>
1246 operator*(const Mat4<T0> &m0, const Mat4<T1> &m1)
1247 {
1248 Mat4<typename promote<T0, T1>::type> result(m0);
1249 result *= m1;
1250 return result;
1251 }
1252
1253
1257 template<typename T0, typename T1>
1258 Vec3<T1> transformNormal(const Mat4<T0> &m, const Vec3<T1> &n)
1259 {
1260 return Vec3<T1>(
1261 static_cast<T1>(m[0][0]*n[0] + m[0][1]*n[1] + m[0][2]*n[2]),
1262 static_cast<T1>(m[1][0]*n[0] + m[1][1]*n[1] + m[1][2]*n[2]),
1263 static_cast<T1>(m[2][0]*n[0] + m[2][1]*n[1] + m[2][2]*n[2]));
1264 }
1265
1266
1268 template<typename T>
1269 bool Mat4<T>::invert(Mat4<T> &inverse, T tolerance) const
1270 {
1271 Mat4<T> temp(*this);
1272 inverse.setIdentity();
1273
1274 // Forward elimination step
1275 double det = 1.0;
1276 for (int i = 0; i < 4; ++i) {
1277 int row = i;
1278 double max = fabs(temp[i][i]);
1279
1280 for (int k = i+1; k < 4; ++k) {
1281 if (fabs(temp[k][i]) > max) {
1282 row = k;
1283 max = fabs(temp[k][i]);
1284 }
1285 }
1286
1287 if (isExactlyEqual(max, 0.0)) return false;
1288
1289 // must move pivot to row i
1290 if (row != i) {
1291 det = -det;
1292 for (int k = 0; k < 4; ++k) {
1293 std::swap(temp[row][k], temp[i][k]);
1294 std::swap(inverse[row][k], inverse[i][k]);
1295 }
1296 }
1297
1298 double pivot = temp[i][i];
1299 det *= pivot;
1300
1301 // scale row i
1302 for (int k = 0; k < 4; ++k) {
1303 temp[i][k] /= pivot;
1304 inverse[i][k] /= pivot;
1305 }
1306
1307 // eliminate in rows below i
1308 for (int j = i+1; j < 4; ++j) {
1309 double t = temp[j][i];
1310 if (!isExactlyEqual(t, 0.0)) {
1311 // subtract scaled row i from row j
1312 for (int k = 0; k < 4; ++k) {
1313 temp[j][k] -= temp[i][k] * t;
1314 inverse[j][k] -= inverse[i][k] * t;
1315 }
1316 }
1317 }
1318 }
1319
1320 // Backward elimination step
1321 for (int i = 3; i > 0; --i) {
1322 for (int j = 0; j < i; ++j) {
1323 double t = temp[j][i];
1324
1325 if (!isExactlyEqual(t, 0.0)) {
1326 for (int k = 0; k < 4; ++k) {
1327 inverse[j][k] -= inverse[i][k]*t;
1328 }
1329 }
1330 }
1331 }
1332 return det*det >= tolerance*tolerance;
1333 }
1334
1335 template <typename T>
1336 inline bool isAffine(const Mat4<T>& m) {
1337 return (m.col(3) == Vec4<T>(0, 0, 0, 1));
1338 }
1339
1340 template <typename T>
1341 inline bool hasTranslation(const Mat4<T>& m) {
1342 return (m.row(3) != Vec4<T>(0, 0, 0, 1));
1343 }
1344
1345
1346 typedef Mat4<float> Mat4s;
1347 typedef Mat4<double> Mat4d;
1348
1349 #if DWREAL_IS_DOUBLE == 1
1350 typedef Mat4d Mat4f;
1351 #else
1352 typedef Mat4s Mat4f;
1353 #endif // DWREAL_IS_DOUBLE
1354
1355 } // namespace math
1356
1357
1358 template<> inline math::Mat4s zeroVal<math::Mat4s>() { return math::Mat4s::identity(); }
1359 template<> inline math::Mat4d zeroVal<math::Mat4d>() { return math::Mat4d::identity(); }
1360
1361 } // namespace OPENVDB_VERSION_NAME
1362 } // namespace openvdb
1363
1364 #endif // OPENVDB_UTIL_MAT4_H_HAS_BEEN_INCLUDED
1365
1366 // Copyright (c) 2012-2015 DreamWorks Animation LLC
1367 // All rights reserved. This software is distributed under the
1368 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
openvdb::v3_1_0::math::Mat4::postRotate
void postRotate(Axis axis, T angle)
Right multiplies by a rotation clock-wiseabout the given axis into this matrix.
Definition: Mat4.h:890
openvdb::v3_1_0::math::Mat3
3x3 matrix class.
Definition: Mat3.h:54
openvdb::v3_1_0::math::Mat3::asPointer
T * asPointer()
Definition: Mat3.h:201
openvdb::v3_1_0::math::Mat4::asPointer
const T * asPointer() const
Definition: Mat4.h:200
openvdb::v3_1_0::math::Mat4::row
Vec4< T > row(int i) const
Get ith row, e.g. Vec4f v = m.row(1);.
Definition: Mat4.h:168
openvdb::v3_1_0::math::Mat3::det
T det() const
Determinant of matrix.
Definition: Mat3.h:481
openvdb::v3_1_0::math::Mat4::value_type
T value_type
Data type held by the matrix.
Definition: Mat4.h:61
Vec3.h
openvdb::v3_1_0::math::Mat4::inverse
Mat4 inverse(T tolerance=0) const
Definition: Mat4.h:490
openvdb::v3_1_0::math::Mat4::operator*=
const Mat4< T > & operator*=(S scalar)
Return m, where for .
Definition: Mat4.h:360
openvdb::v3_1_0::math::Mat4::transform
Vec4< T0 > transform(const Vec4< T0 > &v) const
Transform a Vec4 by post-multiplication.
Definition: Mat4.h:1010
openvdb::v3_1_0::math::Mat4::operator*=
const Mat4< T > & operator*=(const Mat4< S > &m1)
Return m, where for .
Definition: Mat4.h:444
Math.h
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
openvdb::v3_1_0::math::Mat4::operator=
const Mat4 & operator=(const Mat4< Source > &m)
Assignment operator.
Definition: Mat4.h:328
openvdb::v3_1_0::math::Mat4::setToRotation
void setToRotation(Axis axis, T angle)
Sets the matrix to a rotation about the given axis.
Definition: Mat4.h:795
openvdb::v3_1_0::math::Mat4::preShear
void preShear(Axis axis0, Axis axis1, T shear)
Left multiplies a shearing transformation into the matrix.
Definition: Mat4.h:980
openvdb::v3_1_0::math::isExactlyEqual
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:407
openvdb::v3_1_0::math::Z_AXIS
Definition: Math.h:841
openvdb::v3_1_0::math::Mat4::getMat3
Mat3< T > getMat3() const
Definition: Mat4.h:302
openvdb::v3_1_0::math::Mat4::operator*
Mat4< typename promote< S, T >::type > operator*(S scalar, const Mat4< T > &m)
Returns M, where for .
Definition: Mat4.h:1144
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
openvdb::v3_1_0::math::Mat4::operator()
T & operator()(int i, int j)
Definition: Mat4.h:205
openvdb::v3_1_0::math::Mat4::pretransform
Vec3< T0 > pretransform(const Vec3< T0 > &v) const
Transform a Vec3 by pre-multiplication, without homogenous division.
Definition: Mat4.h:1031
openvdb::v3_1_0::math::Mat::mm
T mm[SIZE *SIZE]
Definition: Mat.h:141
openvdb::v3_1_0::math::Mat
Definition: Mat.h:52
openvdb::v3_1_0::math::Mat4::getTranslation
Vec3< T > getTranslation() const
Return the translation component.
Definition: Mat4.h:314
openvdb::v3_1_0::math::Mat4::setToRotation
void setToRotation(const Vec3< T > &axis, T angle)
Sets the matrix to a rotation about an arbitrary axis.
Definition: Mat4.h:800
openvdb::v3_1_0::math::Mat4::setBasis
void setBasis(const Vec4< T > &v1, const Vec4< T > &v2, const Vec4< T > &v3, const Vec4< T > &v4)
Set the columns of "this" matrix to the vectors v1, v2, v3, v4.
Definition: Mat4.h:223
openvdb::v3_1_0::math::Mat4::asPointer
T * asPointer()
Direct access to the internal data.
Definition: Mat4.h:199
openvdb::v3_1_0::math::Vec3::y
T & y()
Definition: Vec3.h:98
openvdb::v3_1_0::math::Mat4::col
Vec4< T > col(int j) const
Get jth column, e.g. Vec4f v = m.col(0);.
Definition: Mat4.h:185
openvdb::v3_1_0::math::Mat4::transformH
Vec3< T0 > transformH(const Vec3< T0 > &p) const
Transform a Vec3 by post-multiplication, doing homogenous divison.
Definition: Mat4.h:1038
openvdb::v3_1_0::math::isApproxEqual
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
openvdb::v3_1_0::math::Mat4::snapBasis
Mat4 snapBasis(Axis axis, const Vec3< T > &direction)
Definition: Mat4.h:675
openvdb::v3_1_0::math::Mat4::transform3x3
Vec3< T0 > transform3x3(const Vec3< T0 > &v) const
Transform a Vec3 by post-multiplication, without translation.
Definition: Mat4.h:1081
openvdb::v3_1_0::math::angle
T angle(const Vec2< T > &v1, const Vec2< T > &v2)
Definition: Vec2.h:446
Mat3.h
openvdb::v3_1_0::math::Vec4
Definition: Mat4.h:51
openvdb::v3_1_0::math::Mat4::setMat3
void setMat3(const Mat3< T > &m)
Set upper left to a Mat3.
Definition: Mat4.h:295
openvdb::v3_1_0::math::Mat4::operator+=
const Mat4< T > & operator+=(const Mat4< S > &m1)
Returns m0, where for .
Definition: Mat4.h:386
openvdb::v3_1_0::math::Mat4::preTranslate
void preTranslate(const Vec3< T0 > &tr)
Left multiples by the specified translation, i.e. Trans * (*this)
Definition: Mat4.h:715
openvdb::v3_1_0::math::Mat4f
Mat4s Mat4f
Definition: Mat4.h:1352
openvdb::v3_1_0::math::Mat4::operator*
Vec4< typename promote< T, MT >::type > operator*(const Mat4< MT > &_m, const Vec4< T > &_v)
Returns v, where for .
Definition: Mat4.h:1163
openvdb::v3_1_0::math::Mat4::operator-
Mat4< T > operator-() const
Negation operator, for e.g. m1 = -m2;.
Definition: Mat4.h:348
openvdb::v3_1_0::math::Mat4::identity
static const Mat4< T > & identity()
Predefined constant for identity matrix.
Definition: Mat4.h:147
openvdb::v3_1_0::math::Mat4::operator*
Mat4< typename promote< S, T >::type > operator*(const Mat4< T > &m, S scalar)
Returns M, where for .
Definition: Mat4.h:1152
openvdb::v3_1_0::math::Mat4::setTranslation
void setTranslation(const Vec3< T > &t)
Definition: Mat4.h:319
openvdb::v3_1_0::math::Mat4::Mat4
Mat4(const Mat4< Source > &m)
Conversion constructor.
Definition: Mat4.h:137
openvdb::v3_1_0::math::Mat4::setIdentity
void setIdentity()
Set "this" matrix to identity.
Definition: Mat4.h:270
openvdb::v3_1_0::math::Mat4::Mat4
Mat4(const Mat< 4, T > &m)
Copy constructor.
Definition: Mat4.h:126
Exceptions.h
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
Definition: version.h:43
openvdb::v3_1_0::math::Mat4::det
T det() const
Determinant of matrix.
Definition: Mat4.h:642
openvdb::v3_1_0::math::Mat4::operator()
T operator()(int i, int j) const
Definition: Mat4.h:215
openvdb::v3_1_0::math::Mat4::setToScale
void setToScale(const Vec3< T0 > &v)
Sets the matrix to a matrix that scales by v.
Definition: Mat4.h:738
openvdb::v3_1_0::math::Mat4d
Mat4< double > Mat4d
Definition: Mat4.h:1347
openvdb::v3_1_0::math::Mat4::pretransform
Vec4< T0 > pretransform(const Vec4< T0 > &v) const
Transform a Vec4 by pre-multiplication.
Definition: Mat4.h:1024
openvdb::v3_1_0::math::Mat4s
Mat4< float > Mat4s
Definition: Mat4.h:1346
openvdb::v3_1_0::math::Mat4::postTranslate
void postTranslate(const Vec3< T0 > &tr)
Right multiplies by the specified translation matrix, i.e. (*this) * Trans.
Definition: Mat4.h:726
openvdb::v3_1_0::math::Mat4::operator!=
bool operator!=(const Mat4< T0 > &m0, const Mat4< T1 > &m1)
Inequality operator, does exact floating point comparisons.
Definition: Mat4.h:1139
openvdb::v3_1_0::math::Vec3
Definition: Mat.h:146
openvdb::v3_1_0::math::transformNormal
Vec3< T1 > transformNormal(const Mat4< T0 > &m, const Vec3< T1 > &n)
Definition: Mat4.h:1258
openvdb::v3_1_0::math::Mat4::postScale
void postScale(const Vec3< T0 > &v)
Definition: Mat4.h:770
openvdb::v3_1_0::math::Mat4::operator*
Mat4< typename promote< T0, T1 >::type > operator*(const Mat4< T0 > &m0, const Mat4< T1 > &m1)
Returns M, where for .
Definition: Mat4.h:1246
openvdb
Definition: Exceptions.h:39
openvdb::v3_1_0::math::shear
MatType shear(Axis axis0, Axis axis1, typename MatType::value_type shear)
Set the matrix to a shear along axis0 by a fraction of axis1.
Definition: Mat.h:667
openvdb::v3_1_0::math::Mat4::Mat4
Mat4(Source a, Source b, Source c, Source d, Source e, Source f, Source g, Source h, Source i, Source j, Source k, Source l, Source m, Source n, Source o, Source p)
Constructor given array of elements, the ordering is in row major form:
Definition: Mat4.h:91
openvdb::v3_1_0::math::Mat4::postShear
void postShear(Axis axis0, Axis axis1, T shear)
Right multiplies a shearing transformation into the matrix.
Definition: Mat4.h:995
openvdb::v3_1_0::math::Mat4::operator[]
const T * operator[](int i) const
Definition: Mat4.h:195
openvdb::v3_1_0::math::Mat4::operator*
Vec3< typename promote< T, MT >::type > operator*(const Vec3< T > &_v, const Mat4< MT > &_m)
Returns v, where for .
Definition: Mat4.h:1209
openvdb::v3_1_0::math::Y_AXIS
Definition: Math.h:840
openvdb::v3_1_0::math::Vec3::z
T & z()
Definition: Vec3.h:99
openvdb::v3_1_0::math::isAffine
bool isAffine(const Mat4< T > &m)
Definition: Mat4.h:1336
openvdb::v3_1_0::math::Axis
Axis
Definition: Math.h:838
openvdb::v3_1_0::math::Mat4::setRow
void setRow(int i, const Vec4< T > &v)
Set ith row to vector v.
Definition: Mat4.h:157
openvdb::v3_1_0::math::hasTranslation
bool hasTranslation(const Mat4< T > &m)
Definition: Mat4.h:1341
openvdb::v3_1_0::math::Mat4::setToShear
void setToShear(Axis axis0, Axis axis1, T shearby)
Sets the matrix to a shear along axis0 by a fraction of axis1.
Definition: Mat4.h:972
openvdb::v3_1_0::math::Mat4::operator-=
const Mat4< T > & operator-=(const Mat4< S > &m1)
Returns m0, where for .
Definition: Mat4.h:415
openvdb::v3_1_0::math::Mat4::pretransformH
Vec3< T0 > pretransformH(const Vec3< T0 > &p) const
Transform a Vec3 by pre-multiplication, doing homogenous division.
Definition: Mat4.h:1060
openvdb::v3_1_0::math::Mat4::ValueType
T ValueType
Definition: Mat4.h:62
openvdb::v3_1_0::math::Mat4::setCol
void setCol(int j, const Vec4< T > &v)
Set jth column to vector v.
Definition: Mat4.h:175
openvdb::v3_1_0::tools::composite::max
const boost::disable_if_c< VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:109
openvdb::v3_1_0::math::Mat4::Mat4
Mat4()
Trivial constructor, the matrix is NOT initialized.
Definition: Mat4.h:66
openvdb::v3_1_0::math::Mat4::MyBase
Mat< 4, T > MyBase
Definition: Mat4.h:63
openvdb::v3_1_0::ArithmeticError
Definition: Exceptions.h:78
openvdb::v3_1_0::math::Mat4
4x4 -matrix class.
Definition: Mat3.h:48
openvdb::v3_1_0::math::Mat4::translation
static Mat4 translation(const Vec3d &v)
Sets the matrix to a matrix that translates by v.
Definition: Mat4.h:679
openvdb::v3_1_0::math::Mat4::setToRotation
void setToRotation(const Vec3< T > &v1, const Vec3< T > &v2)
Sets the matrix to a rotation that maps v1 onto v2 about the cross product of v1 and v2...
Definition: Mat4.h:804
openvdb::v3_1_0::math::Mat4::setZero
void setZero()
Definition: Mat4.h:249
openvdb::v3_1_0::math::Mat4::Mat4
Mat4(Source *a)
Constructor given array of elements, the ordering is in row major form:
Definition: Mat4.h:76
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
openvdb::v3_1_0::math::Mat4::preScale
void preScale(const Vec3< T0 > &v)
Definition: Mat4.h:748
openvdb::v3_1_0::math::Mat4::operator*
Vec4< typename promote< T, MT >::type > operator*(const Vec4< T > &_v, const Mat4< MT > &_m)
Returns v, where for .
Definition: Mat4.h:1178
openvdb::v3_1_0::math::Mat4::transform
Vec3< T0 > transform(const Vec3< T0 > &v) const
Transform a Vec3 by post-multiplication, without homogenous division.
Definition: Mat4.h:1017
openvdb::v3_1_0::math::Mat4::transpose
Mat4 transpose() const
Definition: Mat4.h:477
openvdb::v3_1_0::math::Mat4::setToTranslation
void setToTranslation(const Vec3< T0 > &v)
Sets the matrix to a matrix that translates by v.
Definition: Mat4.h:690
openvdb::v3_1_0::math::Vec3::dot
T dot(const Vec3< T > &v) const
Dot product.
Definition: Vec3.h:203
openvdb::v3_1_0::math::X_AXIS
Definition: Math.h:839
openvdb::v3_1_0::math::Mat4::zero
static const Mat4< T > & zero()
Predefined constant for zero matrix.
Definition: Mat4.h:152
openvdb::v3_1_0::math::Mat4::Mat4
Mat4(const Vec4< Source > &v1, const Vec4< Source > &v2, const Vec4< Source > &v3, const Vec4< Source > &v4)
Construct matrix given basis vectors (columns)
Definition: Mat4.h:119
openvdb::v3_1_0::math::Mat4::preRotate
void preRotate(Axis axis, T angle)
Left multiplies by a rotation clock-wiseabout the given axis into this matrix.
Definition: Mat4.h:810
openvdb::v3_1_0::math::Mat4::operator==
bool operator==(const Mat4< T0 > &m0, const Mat4< T1 > &m1)
Equality operator, does exact floating point comparisons.
Definition: Mat4.h:1127
openvdb::v3_1_0::math::Mat4::operator-
Mat4< typename promote< T0, T1 >::type > operator-(const Mat4< T0 > &m0, const Mat4< T1 > &m1)
Returns M, where for .
Definition: Mat4.h:1234
openvdb::v3_1_0::math::Mat4::operator+
Mat4< typename promote< T0, T1 >::type > operator+(const Mat4< T0 > &m0, const Mat4< T1 > &m1)
Returns M, where for .
Definition: Mat4.h:1223
openvdb::v3_1_0::math::Vec3::x
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:97
openvdb::v3_1_0::math::Mat4::eq
bool eq(const Mat4 &m, T eps=1.0e-8) const
Test if "this" is equivalent to m with tolerance of eps value.
Definition: Mat4.h:338
Platform.h
openvdb::v3_1_0::math::Mat4::operator*
Vec3< typename promote< T, MT >::type > operator*(const Mat4< MT > &_m, const Vec3< T > &_v)
Returns v, where for .
Definition: Mat4.h:1194
Vec4.h