OpenVDB  3.1.0
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 {
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 
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 
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>
1025  {
1026  return static_cast< Vec4<T0> >(*this * v);
1027  }
1028 
1030  template<typename T0>
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>
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>
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>
1145 {
1146  return m*scalar;
1147 }
1148 
1151 template <typename S, typename T>
1153 {
1155  result *= scalar;
1156  return result;
1157 }
1158 
1161 template<typename T, typename MT>
1164  const Vec4<T> &_v)
1165 {
1166  MT const *m = _m.asPointer();
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>
1178 operator*(const Vec4<T> &_v,
1179  const Mat4<MT> &_m)
1180 {
1181  MT const *m = _m.asPointer();
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>
1195  const Vec3<T> &_v)
1196 {
1197  MT const *m = _m.asPointer();
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>
1209 operator*(const Vec3<T> &_v,
1210  const Mat4<MT> &_m)
1211 {
1212  MT const *m = _m.asPointer();
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>
1223 operator+(const Mat4<T0> &m0, const Mat4<T1> &m1)
1224 {
1226  result += m1;
1227  return result;
1228 }
1229 
1232 template <typename T0, typename T1>
1234 operator-(const Mat4<T0> &m0, const Mat4<T1> &m1)
1235 {
1237  result -= m1;
1238  return result;
1239 }
1240 
1244 template <typename T0, typename T1>
1246 operator*(const Mat4<T0> &m0, const Mat4<T1> &m1)
1247 {
1249  result *= m1;
1250  return result;
1251 }
1252 
1253 
1257 template<typename T0, typename T1>
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 
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/ )
void postRotate(Axis axis, T angle)
Right multiplies by a rotation clock-wiseabout the given axis into this matrix.
Definition: Mat4.h:890
3x3 matrix class.
Definition: Mat3.h:54
T * asPointer()
Definition: Mat3.h:201
const T * asPointer() const
Definition: Mat4.h:200
Vec4< T > row(int i) const
Get ith row, e.g. Vec4f v = m.row(1);.
Definition: Mat4.h:168
T det() const
Determinant of matrix.
Definition: Mat3.h:481
T value_type
Data type held by the matrix.
Definition: Mat4.h:61
Mat4 inverse(T tolerance=0) const
Definition: Mat4.h:490
const Mat4< T > & operator*=(S scalar)
Return m, where for .
Definition: Mat4.h:360
Vec4< T0 > transform(const Vec4< T0 > &v) const
Transform a Vec4 by post-multiplication.
Definition: Mat4.h:1010
const Mat4< T > & operator*=(const Mat4< S > &m1)
Return m, where for .
Definition: Mat4.h:444
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
const Mat4 & operator=(const Mat4< Source > &m)
Assignment operator.
Definition: Mat4.h:328
void setToRotation(Axis axis, T angle)
Sets the matrix to a rotation about the given axis.
Definition: Mat4.h:795
void preShear(Axis axis0, Axis axis1, T shear)
Left multiplies a shearing transformation into the matrix.
Definition: Mat4.h:980
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:407
Definition: Math.h:841
Mat3< T > getMat3() const
Definition: Mat4.h:302
Mat4< typename promote< S, T >::type > operator*(S scalar, const Mat4< T > &m)
Returns M, where for .
Definition: Mat4.h:1144
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
T & operator()(int i, int j)
Definition: Mat4.h:205
Vec3< T0 > pretransform(const Vec3< T0 > &v) const
Transform a Vec3 by pre-multiplication, without homogenous division.
Definition: Mat4.h:1031
T mm[SIZE *SIZE]
Definition: Mat.h:141
Definition: Mat.h:52
Vec3< T > getTranslation() const
Return the translation component.
Definition: Mat4.h:314
void setToRotation(const Vec3< T > &axis, T angle)
Sets the matrix to a rotation about an arbitrary axis.
Definition: Mat4.h:800
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
T * asPointer()
Direct access to the internal data.
Definition: Mat4.h:199
T & y()
Definition: Vec3.h:98
Vec4< T > col(int j) const
Get jth column, e.g. Vec4f v = m.col(0);.
Definition: Mat4.h:185
Vec3< T0 > transformH(const Vec3< T0 > &p) const
Transform a Vec3 by post-multiplication, doing homogenous divison.
Definition: Mat4.h:1038
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
Mat4 snapBasis(Axis axis, const Vec3< T > &direction)
Definition: Mat4.h:675
Vec3< T0 > transform3x3(const Vec3< T0 > &v) const
Transform a Vec3 by post-multiplication, without translation.
Definition: Mat4.h:1081
T angle(const Vec2< T > &v1, const Vec2< T > &v2)
Definition: Vec2.h:446
Definition: Mat4.h:51
void setMat3(const Mat3< T > &m)
Set upper left to a Mat3.
Definition: Mat4.h:295
const Mat4< T > & operator+=(const Mat4< S > &m1)
Returns m0, where for .
Definition: Mat4.h:386
void preTranslate(const Vec3< T0 > &tr)
Left multiples by the specified translation, i.e. Trans * (*this)
Definition: Mat4.h:715
Mat4s Mat4f
Definition: Mat4.h:1352
Vec4< typename promote< T, MT >::type > operator*(const Mat4< MT > &_m, const Vec4< T > &_v)
Returns v, where for .
Definition: Mat4.h:1163
Mat4< T > operator-() const
Negation operator, for e.g. m1 = -m2;.
Definition: Mat4.h:348
static const Mat4< T > & identity()
Predefined constant for identity matrix.
Definition: Mat4.h:147
Mat4< typename promote< S, T >::type > operator*(const Mat4< T > &m, S scalar)
Returns M, where for .
Definition: Mat4.h:1152
void setTranslation(const Vec3< T > &t)
Definition: Mat4.h:319
Mat4(const Mat4< Source > &m)
Conversion constructor.
Definition: Mat4.h:137
void setIdentity()
Set "this" matrix to identity.
Definition: Mat4.h:270
Mat4(const Mat< 4, T > &m)
Copy constructor.
Definition: Mat4.h:126
#define OPENVDB_VERSION_NAME
Definition: version.h:43
T det() const
Determinant of matrix.
Definition: Mat4.h:642
T operator()(int i, int j) const
Definition: Mat4.h:215
void setToScale(const Vec3< T0 > &v)
Sets the matrix to a matrix that scales by v.
Definition: Mat4.h:738
Mat4< double > Mat4d
Definition: Mat4.h:1347
Vec4< T0 > pretransform(const Vec4< T0 > &v) const
Transform a Vec4 by pre-multiplication.
Definition: Mat4.h:1024
Mat4< float > Mat4s
Definition: Mat4.h:1346
void postTranslate(const Vec3< T0 > &tr)
Right multiplies by the specified translation matrix, i.e. (*this) * Trans.
Definition: Mat4.h:726
bool operator!=(const Mat4< T0 > &m0, const Mat4< T1 > &m1)
Inequality operator, does exact floating point comparisons.
Definition: Mat4.h:1139
Definition: Mat.h:146
Vec3< T1 > transformNormal(const Mat4< T0 > &m, const Vec3< T1 > &n)
Definition: Mat4.h:1258
void postScale(const Vec3< T0 > &v)
Definition: Mat4.h:770
Mat4< typename promote< T0, T1 >::type > operator*(const Mat4< T0 > &m0, const Mat4< T1 > &m1)
Returns M, where for .
Definition: Mat4.h:1246
Definition: Exceptions.h:39
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
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
void postShear(Axis axis0, Axis axis1, T shear)
Right multiplies a shearing transformation into the matrix.
Definition: Mat4.h:995
const T * operator[](int i) const
Definition: Mat4.h:195
Vec3< typename promote< T, MT >::type > operator*(const Vec3< T > &_v, const Mat4< MT > &_m)
Returns v, where for .
Definition: Mat4.h:1209
Definition: Math.h:840
T & z()
Definition: Vec3.h:99
bool isAffine(const Mat4< T > &m)
Definition: Mat4.h:1336
Axis
Definition: Math.h:838
void setRow(int i, const Vec4< T > &v)
Set ith row to vector v.
Definition: Mat4.h:157
bool hasTranslation(const Mat4< T > &m)
Definition: Mat4.h:1341
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
const Mat4< T > & operator-=(const Mat4< S > &m1)
Returns m0, where for .
Definition: Mat4.h:415
Vec3< T0 > pretransformH(const Vec3< T0 > &p) const
Transform a Vec3 by pre-multiplication, doing homogenous division.
Definition: Mat4.h:1060
T ValueType
Definition: Mat4.h:62
void setCol(int j, const Vec4< T > &v)
Set jth column to vector v.
Definition: Mat4.h:175
const boost::disable_if_c< VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:109
Mat4()
Trivial constructor, the matrix is NOT initialized.
Definition: Mat4.h:66
Mat< 4, T > MyBase
Definition: Mat4.h:63
Definition: Exceptions.h:78
4x4 -matrix class.
Definition: Mat3.h:48
static Mat4 translation(const Vec3d &v)
Sets the matrix to a matrix that translates by v.
Definition: Mat4.h:679
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
void setZero()
Definition: Mat4.h:249
Mat4(Source *a)
Constructor given array of elements, the ordering is in row major form:
Definition: Mat4.h:76
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
void preScale(const Vec3< T0 > &v)
Definition: Mat4.h:748
Vec4< typename promote< T, MT >::type > operator*(const Vec4< T > &_v, const Mat4< MT > &_m)
Returns v, where for .
Definition: Mat4.h:1178
Vec3< T0 > transform(const Vec3< T0 > &v) const
Transform a Vec3 by post-multiplication, without homogenous division.
Definition: Mat4.h:1017
Mat4 transpose() const
Definition: Mat4.h:477
void setToTranslation(const Vec3< T0 > &v)
Sets the matrix to a matrix that translates by v.
Definition: Mat4.h:690
T dot(const Vec3< T > &v) const
Dot product.
Definition: Vec3.h:203
Definition: Math.h:839
static const Mat4< T > & zero()
Predefined constant for zero matrix.
Definition: Mat4.h:152
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
void preRotate(Axis axis, T angle)
Left multiplies by a rotation clock-wiseabout the given axis into this matrix.
Definition: Mat4.h:810
bool operator==(const Mat4< T0 > &m0, const Mat4< T1 > &m1)
Equality operator, does exact floating point comparisons.
Definition: Mat4.h:1127
Mat4< typename promote< T0, T1 >::type > operator-(const Mat4< T0 > &m0, const Mat4< T1 > &m1)
Returns M, where for .
Definition: Mat4.h:1234
Mat4< typename promote< T0, T1 >::type > operator+(const Mat4< T0 > &m0, const Mat4< T1 > &m1)
Returns M, where for .
Definition: Mat4.h:1223
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:97
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
Vec3< typename promote< T, MT >::type > operator*(const Mat4< MT > &_m, const Vec3< T > &_v)
Returns v, where for .
Definition: Mat4.h:1194