OpenVDB  2.3.0
Mat4.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2013 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] = a;
97  MyBase::mm[ 1] = b;
98  MyBase::mm[ 2] = c;
99  MyBase::mm[ 3] = d;
100 
101  MyBase::mm[ 4] = e;
102  MyBase::mm[ 5] = f;
103  MyBase::mm[ 6] = g;
104  MyBase::mm[ 7] = h;
105 
106  MyBase::mm[ 8] = i;
107  MyBase::mm[ 9] = j;
108  MyBase::mm[10] = k;
109  MyBase::mm[11] = l;
110 
111  MyBase::mm[12] = m;
112  MyBase::mm[13] = n;
113  MyBase::mm[14] = o;
114  MyBase::mm[15] = 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 = p[0] * MyBase::mm[ 3] + p[1] * MyBase::mm[ 7] + p[2] * MyBase::mm[11] + MyBase::mm[15];
1044 
1045  if ( !isExactlyEqual(w , 0.0) ) {
1046  return Vec3<T0>(static_cast<T0>((p[0] * MyBase::mm[ 0] + p[1] * MyBase::mm[ 4] +
1047  p[2] * MyBase::mm[ 8] + MyBase::mm[12]) / w),
1048  static_cast<T0>((p[0] * MyBase::mm[ 1] + p[1] * MyBase::mm[ 5] +
1049  p[2] * MyBase::mm[ 9] + MyBase::mm[13]) / w),
1050  static_cast<T0>((p[0] * MyBase::mm[ 2] + p[1] * MyBase::mm[ 6] +
1051  p[2] * MyBase::mm[10] + MyBase::mm[14]) / w));
1052  }
1053 
1054  return Vec3<T0>(0, 0, 0);
1055  }
1056 
1058  template<typename T0>
1060  {
1061  T0 w;
1062 
1063  // w = p * (*this).col(3);
1064  w = p[0] * MyBase::mm[12] + p[1] * MyBase::mm[13] + p[2] * MyBase::mm[14] + MyBase::mm[15];
1065 
1066  if ( !isExactlyEqual(w , 0.0) ) {
1067  return Vec3<T0>(static_cast<T0>((p[0] * MyBase::mm[ 0] + p[1] * MyBase::mm[ 1] +
1068  p[2] * MyBase::mm[ 2] + MyBase::mm[ 3]) / w),
1069  static_cast<T0>((p[0] * MyBase::mm[ 4] + p[1] * MyBase::mm[ 5] +
1070  p[2] * MyBase::mm[ 6] + MyBase::mm[ 7]) / w),
1071  static_cast<T0>((p[0] * MyBase::mm[ 8] + p[1] * MyBase::mm[ 9] +
1072  p[2] * MyBase::mm[10] + MyBase::mm[11]) / w));
1073  }
1074 
1075  return Vec3<T0>(0, 0, 0);
1076  }
1077 
1079  template<typename T0>
1081  {
1082  return Vec3<T0>(
1083  static_cast<T0>(v[0] * MyBase::mm[ 0] + v[1] * MyBase::mm[ 4] + v[2] * MyBase::mm[ 8]),
1084  static_cast<T0>(v[0] * MyBase::mm[ 1] + v[1] * MyBase::mm[ 5] + v[2] * MyBase::mm[ 9]),
1085  static_cast<T0>(v[0] * MyBase::mm[ 2] + v[1] * MyBase::mm[ 6] + v[2] * MyBase::mm[10]));
1086  }
1087 
1088 
1089 private:
1090  bool invert(Mat4<T> &inverse, T tolerance) const;
1091 
1092  T det2(const Mat4<T> &a, int i0, int i1, int j0, int j1) const {
1093  int i0row = i0 * 4;
1094  int i1row = i1 * 4;
1095  return a.mm[i0row+j0]*a.mm[i1row+j1] - a.mm[i0row+j1]*a.mm[i1row+j0];
1096  }
1097 
1098  T det3(const Mat4<T> &a, int i0, int i1, int i2,
1099  int j0, int j1, int j2) const {
1100  int i0row = i0 * 4;
1101  return a.mm[i0row+j0]*det2(a, i1,i2, j1,j2) +
1102  a.mm[i0row+j1]*det2(a, i1,i2, j2,j0) +
1103  a.mm[i0row+j2]*det2(a, i1,i2, j0,j1);
1104  }
1105 
1106  static const Mat4<T> sIdentity;
1107  static const Mat4<T> sZero;
1108 }; // class Mat4
1109 
1110 
1111 template <typename T>
1112 const Mat4<T> Mat4<T>::sIdentity = Mat4<T>(1, 0, 0, 0,
1113  0, 1, 0, 0,
1114  0, 0, 1, 0,
1115  0, 0, 0, 1);
1116 
1117 template <typename T>
1118 const Mat4<T> Mat4<T>::sZero = Mat4<T>(0, 0, 0, 0,
1119  0, 0, 0, 0,
1120  0, 0, 0, 0,
1121  0, 0, 0, 0);
1122 
1125 template <typename T0, typename T1>
1126 bool operator==(const Mat4<T0> &m0, const Mat4<T1> &m1)
1127 {
1128  const T0 *t0 = m0.asPointer();
1129  const T1 *t1 = m1.asPointer();
1130 
1131  for (int i=0; i<16; ++i) if (!isExactlyEqual(t0[i], t1[i])) return false;
1132  return true;
1133 }
1134 
1137 template <typename T0, typename T1>
1138 bool operator!=(const Mat4<T0> &m0, const Mat4<T1> &m1) { return !(m0 == m1); }
1139 
1142 template <typename S, typename T>
1144 {
1145  return m*scalar;
1146 }
1147 
1150 template <typename S, typename T>
1152 {
1154  result *= scalar;
1155  return result;
1156 }
1157 
1160 template<typename T, typename MT>
1163  const Vec4<T> &_v)
1164 {
1165  MT const *m = _m.asPointer();
1167  _v[0]*m[0] + _v[1]*m[1] + _v[2]*m[2] + _v[3]*m[3],
1168  _v[0]*m[4] + _v[1]*m[5] + _v[2]*m[6] + _v[3]*m[7],
1169  _v[0]*m[8] + _v[1]*m[9] + _v[2]*m[10] + _v[3]*m[11],
1170  _v[0]*m[12] + _v[1]*m[13] + _v[2]*m[14] + _v[3]*m[15]);
1171 }
1172 
1175 template<typename T, typename MT>
1177 operator*(const Vec4<T> &_v,
1178  const Mat4<MT> &_m)
1179 {
1180  MT const *m = _m.asPointer();
1182  _v[0]*m[0] + _v[1]*m[4] + _v[2]*m[8] + _v[3]*m[12],
1183  _v[0]*m[1] + _v[1]*m[5] + _v[2]*m[9] + _v[3]*m[13],
1184  _v[0]*m[2] + _v[1]*m[6] + _v[2]*m[10] + _v[3]*m[14],
1185  _v[0]*m[3] + _v[1]*m[7] + _v[2]*m[11] + _v[3]*m[15]);
1186 }
1187 
1191 template<typename T, typename MT>
1194  const Vec3<T> &_v)
1195 {
1196  MT const *m = _m.asPointer();
1198  _v[0]*m[0] + _v[1]*m[1] + _v[2]*m[2] + m[3],
1199  _v[0]*m[4] + _v[1]*m[5] + _v[2]*m[6] + m[7],
1200  _v[0]*m[8] + _v[1]*m[9] + _v[2]*m[10] + m[11]);
1201 }
1202 
1206 template<typename T, typename MT>
1208 operator*(const Vec3<T> &_v,
1209  const Mat4<MT> &_m)
1210 {
1211  MT const *m = _m.asPointer();
1213  _v[0]*m[0] + _v[1]*m[4] + _v[2]*m[8] + m[12],
1214  _v[0]*m[1] + _v[1]*m[5] + _v[2]*m[9] + m[13],
1215  _v[0]*m[2] + _v[1]*m[6] + _v[2]*m[10] + m[14]);
1216 }
1217 
1220 template <typename T0, typename T1>
1222 operator+(const Mat4<T0> &m0, const Mat4<T1> &m1)
1223 {
1225  result += m1;
1226  return result;
1227 }
1228 
1231 template <typename T0, typename T1>
1233 operator-(const Mat4<T0> &m0, const Mat4<T1> &m1)
1234 {
1236  result -= m1;
1237  return result;
1238 }
1239 
1243 template <typename T0, typename T1>
1245 operator*(const Mat4<T0> &m0, const Mat4<T1> &m1)
1246 {
1248  result *= m1;
1249  return result;
1250 }
1251 
1252 
1256 template<typename T0, typename T1>
1258 {
1259  return Vec3<T1>(
1260  static_cast<T1>(m[0][0]*n[0] + m[0][1]*n[1] + m[0][2]*n[2]),
1261  static_cast<T1>(m[1][0]*n[0] + m[1][1]*n[1] + m[1][2]*n[2]),
1262  static_cast<T1>(m[2][0]*n[0] + m[2][1]*n[1] + m[2][2]*n[2]));
1263 }
1264 
1265 
1267 template<typename T>
1268 bool Mat4<T>::invert(Mat4<T> &inverse, T tolerance) const
1269 {
1270  Mat4<T> temp(*this);
1271  inverse.setIdentity();
1272 
1273  // Forward elimination step
1274  double det = 1.0;
1275  for (int i = 0; i < 4; ++i) {
1276  int row = i;
1277  double max = fabs(temp[i][i]);
1278 
1279  for (int k = i+1; k < 4; ++k) {
1280  if (fabs(temp[k][i]) > max) {
1281  row = k;
1282  max = fabs(temp[k][i]);
1283  }
1284  }
1285 
1286  if (isExactlyEqual(max, 0.0)) return false;
1287 
1288  // must move pivot to row i
1289  if (row != i) {
1290  det = -det;
1291  for (int k = 0; k < 4; ++k) {
1292  std::swap(temp[row][k], temp[i][k]);
1293  std::swap(inverse[row][k], inverse[i][k]);
1294  }
1295  }
1296 
1297  double pivot = temp[i][i];
1298  det *= pivot;
1299 
1300  // scale row i
1301  for (int k = 0; k < 4; ++k) {
1302  temp[i][k] /= pivot;
1303  inverse[i][k] /= pivot;
1304  }
1305 
1306  // eliminate in rows below i
1307  for (int j = i+1; j < 4; ++j) {
1308  double t = temp[j][i];
1309  if (!isExactlyEqual(t, 0.0)) {
1310  // subtract scaled row i from row j
1311  for (int k = 0; k < 4; ++k) {
1312  temp[j][k] -= temp[i][k] * t;
1313  inverse[j][k] -= inverse[i][k] * t;
1314  }
1315  }
1316  }
1317  }
1318 
1319  // Backward elimination step
1320  for (int i = 3; i > 0; --i) {
1321  for (int j = 0; j < i; ++j) {
1322  double t = temp[j][i];
1323 
1324  if (!isExactlyEqual(t, 0.0)) {
1325  for (int k = 0; k < 4; ++k) {
1326  inverse[j][k] -= inverse[i][k]*t;
1327  }
1328  }
1329  }
1330  }
1331  return det*det >= tolerance*tolerance;
1332 }
1333 
1334 template <typename T>
1335 inline bool isAffine(const Mat4<T>& m) {
1336  return (m.col(3) == Vec4<T>(0, 0, 0, 1));
1337 }
1338 
1339 template <typename T>
1340 inline bool hasTranslation(const Mat4<T>& m) {
1341  return (m.row(3) != Vec4<T>(0, 0, 0, 1));
1342 }
1343 
1344 
1347 
1348 #if DWREAL_IS_DOUBLE == 1
1349 typedef Mat4d Mat4f;
1350 #else
1351 typedef Mat4s Mat4f;
1352 #endif // DWREAL_IS_DOUBLE
1353 
1354 } // namespace math
1355 
1356 
1357 template<> inline math::Mat4s zeroVal<math::Mat4s>() { return math::Mat4s::identity(); }
1358 template<> inline math::Mat4d zeroVal<math::Mat4d>() { return math::Mat4d::identity(); }
1359 
1360 } // namespace OPENVDB_VERSION_NAME
1361 } // namespace openvdb
1362 
1363 #endif // OPENVDB_UTIL_MAT4_H_HAS_BEEN_INCLUDED
1364 
1365 // Copyright (c) 2012-2013 DreamWorks Animation LLC
1366 // All rights reserved. This software is distributed under the
1367 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
Vec4< T > row(int i) const
Get ith row, e.g. Vec4f v = m.row(1);.
Definition: Mat4.h:168
4x4 -matrix class.
Definition: Mat3.h:48
Mat4< double > Mat4d
Definition: Mat4.h:1346
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
Mat3< T > getMat3() const
Definition: Mat4.h:302
void postRotate(Axis axis, T angle)
Right multiplies by a rotation clock-wiseabout the given axis into this matrix.
Definition: Mat4.h:890
T * asPointer()
Direct access to the internal data.
Definition: Mat4.h:199
static const Mat4< T > & zero()
Predefined constant for zero matrix.
Definition: Mat4.h:152
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Mat4 snapBasis(Axis axis, const Vec3< T > &direction)
Definition: Mat4.h:675
Definition: Mat.h:52
T & z()
Definition: Vec3.h:96
Vec4< T0 > transform(const Vec4< T0 > &v) const
Transform a Vec4 by post-multiplication.
Definition: Mat4.h:1010
Definition: Exceptions.h:78
Vec3< T0 > transform3x3(const Vec3< T0 > &v) const
Transform a Vec3 by post-multiplication, without translation.
Definition: Mat4.h:1080
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
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
const Mat4< T > & operator*=(S scalar)
Return m, where for .
Definition: Mat4.h:360
Definition: Mat.h:146
void setToRotation(Axis axis, T angle)
Sets the matrix to a rotation about the given axis.
Definition: Mat4.h:795
Mat4< typename promote< S, T >::type > operator*(S scalar, const Mat4< T > &m)
Returns M, where for .
Definition: Mat4.h:1143
const Mat4< T > & operator*=(const Mat4< S > &m1)
Return m, where for .
Definition: Mat4.h:444
T angle(const Vec2< T > &v1, const Vec2< T > &v2)
Definition: Vec2.h:446
3x3 matrix class.
Definition: Mat3.h:54
Definition: Math.h:769
Mat4 inverse(T tolerance=0) const
Definition: Mat4.h:490
static const Mat4< T > & identity()
Predefined constant for identity matrix.
Definition: Mat4.h:147
void preTranslate(const Vec3< T0 > &tr)
Left multiples by the specified translation, i.e. Trans * (*this)
Definition: Mat4.h:715
void preShear(Axis axis0, Axis axis1, T shear)
Left multiplies a shearing transformation into the matrix.
Definition: Mat4.h:980
T det() const
Determinant of matrix.
Definition: Mat4.h:642
void setToScale(const Vec3< T0 > &v)
Sets the matrix to a matrix that scales by v.
Definition: Mat4.h:738
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
Definition: Math.h:768
void setMat3(const Mat3< T > &m)
Set upper left to a Mat3.
Definition: Mat4.h:295
Vec4< T > col(int j) const
Get jth column, e.g. Vec4f v = m.col(0);.
Definition: Mat4.h:185
const Mat4< T > & operator+=(const Mat4< S > &m1)
Returns m0, where for .
Definition: Mat4.h:386
T operator()(int i, int j) const
Definition: Mat4.h:215
T & y()
Definition: Vec3.h:95
Vec4< typename promote< T, MT >::type > operator*(const Mat4< MT > &_m, const Vec4< T > &_v)
Returns v, where for .
Definition: Mat4.h:1162
Mat4< typename promote< T0, T1 >::type > operator*(const Mat4< T0 > &m0, const Mat4< T1 > &m1)
Returns M, where for .
Definition: Mat4.h:1245
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
Mat4(const Mat4< Source > &m)
Conversion constructor.
Definition: Mat4.h:137
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
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:666
const T * operator[](int i) const
Definition: Mat4.h:195
Vec3< T0 > transformH(const Vec3< T0 > &p) const
Transform a Vec3 by post-multiplication, doing homogenous divison.
Definition: Mat4.h:1038
void setTranslation(const Vec3< T > &t)
Definition: Mat4.h:319
#define OPENVDB_VERSION_NAME
Definition: version.h:45
void postScale(const Vec3< T0 > &v)
Definition: Mat4.h:770
bool operator!=(const Mat4< T0 > &m0, const Mat4< T1 > &m1)
Inequality operator, does exact floating point comparisons.
Definition: Mat4.h:1138
bool isAffine(const Mat4< T > &m)
Definition: Mat4.h:1335
T dot(const Vec3< T > &v) const
Dot product.
Definition: Vec3.h:199
OPENVDB_API Hermite max(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
void setIdentity()
Set "this" matrix to identity.
Definition: Mat4.h:270
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:351
Mat4< T > operator-() const
Negation operator, for e.g. m1 = -m2;.
Definition: Mat4.h:348
Mat4< typename promote< S, T >::type > operator*(const Mat4< T > &m, S scalar)
Returns M, where for .
Definition: Mat4.h:1151
Mat4(const Mat< 4, T > &m)
Copy constructor.
Definition: Mat4.h:126
void postShear(Axis axis0, Axis axis1, T shear)
Right multiplies a shearing transformation into the matrix.
Definition: Mat4.h:995
Vec4< T0 > pretransform(const Vec4< T0 > &v) const
Transform a Vec4 by pre-multiplication.
Definition: Mat4.h:1024
void postTranslate(const Vec3< T0 > &tr)
Right multiplies by the specified translation matrix, i.e. (*this) * Trans.
Definition: Mat4.h:726
Mat4< float > Mat4s
Definition: Mat4.h:1345
Vec3< T0 > pretransformH(const Vec3< T0 > &p) const
Transform a Vec3 by pre-multiplication, doing homogenous division.
Definition: Mat4.h:1059
void setRow(int i, const Vec4< T > &v)
Set ith row to vector v.
Definition: Mat4.h:157
Vec3< T1 > transformNormal(const Mat4< T0 > &m, const Vec3< T1 > &n)
Definition: Mat4.h:1257
Vec3< typename promote< T, MT >::type > operator*(const Vec3< T > &_v, const Mat4< MT > &_m)
Returns v, where for .
Definition: Mat4.h:1208
Mat4()
Trivial constructor, the matrix is NOT initialized.
Definition: Mat4.h:66
bool isApproxEqual(const Hermite &lhs, const Hermite &rhs)
Definition: Hermite.h:470
Axis
Definition: Math.h:767
Vec3< T0 > transform(const Vec3< T0 > &v) const
Transform a Vec3 by post-multiplication, without homogenous division.
Definition: Mat4.h:1017
Vec3< typename promote< T, MT >::type > operator*(const Mat4< MT > &_m, const Vec3< T > &_v)
Returns v, where for .
Definition: Mat4.h:1193
void setZero()
Definition: Mat4.h:249
Mat4s Mat4f
Definition: Mat4.h:1351
bool operator==(const Mat4< T0 > &m0, const Mat4< T1 > &m1)
Equality operator, does exact floating point comparisons.
Definition: Mat4.h:1126
void setCol(int j, const Vec4< T > &v)
Set jth column to vector v.
Definition: Mat4.h:175
const Mat4< T > & operator-=(const Mat4< S > &m1)
Returns m0, where for .
Definition: Mat4.h:415
Definition: Math.h:770
const T * asPointer() const
Definition: Mat4.h:200
T * asPointer()
Definition: Mat3.h:201
T mm[SIZE *SIZE]
Definition: Mat.h:141
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:67
T det() const
Determinant of matrix.
Definition: Mat3.h:481
Mat4(Source *a)
Constructor given array of elements, the ordering is in row major form:
Definition: Mat4.h:76
void preScale(const Vec3< T0 > &v)
Definition: Mat4.h:748
void setToTranslation(const Vec3< T0 > &v)
Sets the matrix to a matrix that translates by v.
Definition: Mat4.h:690
Mat4< typename promote< T0, T1 >::type > operator-(const Mat4< T0 > &m0, const Mat4< T1 > &m1)
Returns M, where for .
Definition: Mat4.h:1233
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
bool hasTranslation(const Mat4< T > &m)
Definition: Mat4.h:1340
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:94
Mat< 4, T > MyBase
Definition: Mat4.h:63
T ValueType
Definition: Mat4.h:62
T value_type
Data type held by the matrix.
Definition: Mat4.h:61
Mat4< typename promote< T0, T1 >::type > operator+(const Mat4< T0 > &m0, const Mat4< T1 > &m1)
Returns M, where for .
Definition: Mat4.h:1222
static Mat4 translation(const Vec3d &v)
Sets the matrix to a matrix that translates by v.
Definition: Mat4.h:679
void preRotate(Axis axis, T angle)
Left multiplies by a rotation clock-wiseabout the given axis into this matrix.
Definition: Mat4.h:810
Vec4< typename promote< T, MT >::type > operator*(const Vec4< T > &_v, const Mat4< MT > &_m)
Returns v, where for .
Definition: Mat4.h:1177
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
const Mat4 & operator=(const Mat4< Source > &m)
Assignment operator.
Definition: Mat4.h:328
Mat4 transpose() const
Definition: Mat4.h:477
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
Definition: Mat4.h:51