Loading...
Searching...
No Matches
Mat4.h
Go to the documentation of this file.
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: MPL-2.0
#ifndef OPENVDB_MATH_MAT4_H_HAS_BEEN_INCLUDED
#define OPENVDB_MATH_MAT4_H_HAS_BEEN_INCLUDED
#include <openvdb/Exceptions.h>
#include <openvdb/Platform.h>
#include "Math.h"
#include "Mat3.h"
#include "Vec3.h"
#include "Vec4.h"
#include <algorithm> // for std::copy(), std::swap()
#include <cassert>
#include <iomanip>
#include <cmath>
namespace openvdb {
OPENVDB_USE_VERSION_NAMESPACE
namespace OPENVDB_VERSION_NAME {
namespace math {
template<typename T> class Vec4;
/// @class Mat4 Mat4.h
/// @brief 4x4 -matrix class.
template<typename T>
class Mat4: public Mat<4, T>
{
public:
/// Data type held by the matrix.
using value_type = T;
using ValueType = T;
using MyBase = Mat<4, T>;
/// Trivial constructor, the matrix is NOT initialized
/// @note destructor, copy constructor, assignment operator and
/// move constructor are left to be defined by the compiler (default)
Mat4() = default;
/// Constructor given array of elements, the ordering is in row major form:
/** @verbatim
a[ 0] a[1] a[ 2] a[ 3]
a[ 4] a[5] a[ 6] a[ 7]
a[ 8] a[9] a[10] a[11]
a[12] a[13] a[14] a[15]
@endverbatim */
template<typename Source>
Mat4(Source *a)
{
for (int i = 0; i < 16; i++) {
MyBase::mm[i] = static_cast<T>(a[i]);
}
}
/// Constructor given array of elements, the ordering is in row major form:
/** @verbatim
a b c d
e f g h
i j k l
m n o p
@endverbatim */
template<typename Source>
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)
{
MyBase::mm[ 0] = static_cast<T>(a);
MyBase::mm[ 1] = static_cast<T>(b);
MyBase::mm[ 2] = static_cast<T>(c);
MyBase::mm[ 3] = static_cast<T>(d);
MyBase::mm[ 4] = static_cast<T>(e);
MyBase::mm[ 5] = static_cast<T>(f);
MyBase::mm[ 6] = static_cast<T>(g);
MyBase::mm[ 7] = static_cast<T>(h);
MyBase::mm[ 8] = static_cast<T>(i);
MyBase::mm[ 9] = static_cast<T>(j);
MyBase::mm[10] = static_cast<T>(k);
MyBase::mm[11] = static_cast<T>(l);
MyBase::mm[12] = static_cast<T>(m);
MyBase::mm[13] = static_cast<T>(n);
MyBase::mm[14] = static_cast<T>(o);
MyBase::mm[15] = static_cast<T>(p);
}
/// Construct matrix from rows or columns vectors (defaults to rows
/// for historical reasons)
template<typename Source>
Mat4(const Vec4<Source> &v1, const Vec4<Source> &v2,
const Vec4<Source> &v3, const Vec4<Source> &v4, bool rows = true)
{
if (rows) {
this->setRows(v1, v2, v3, v4);
} else {
this->setColumns(v1, v2, v3, v4);
}
}
/// Conversion constructor
template<typename Source>
explicit Mat4(const Mat4<Source> &m)
{
const Source *src = m.asPointer();
for (int i=0; i<16; ++i) {
MyBase::mm[i] = static_cast<T>(src[i]);
}
}
/// Predefined constant for identity matrix
static const Mat4<T>& identity() {
static const Mat4<T> sIdentity = Mat4<T>(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
);
return sIdentity;
}
/// Predefined constant for zero matrix
static const Mat4<T>& zero() {
static const Mat4<T> sZero = Mat4<T>(
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0
);
return sZero;
}
/// Set ith row to vector v
void setRow(int i, const Vec4<T> &v)
{
// assert(i>=0 && i<4);
int i4 = i * 4;
MyBase::mm[i4+0] = v[0];
MyBase::mm[i4+1] = v[1];
MyBase::mm[i4+2] = v[2];
MyBase::mm[i4+3] = v[3];
}
/// Get ith row, e.g. Vec4f v = m.row(1);
Vec4<T> row(int i) const
{
// assert(i>=0 && i<3);
return Vec4<T>((*this)(i,0), (*this)(i,1), (*this)(i,2), (*this)(i,3));
}
/// Set jth column to vector v
void setCol(int j, const Vec4<T>& v)
{
// assert(j>=0 && j<4);
MyBase::mm[ 0+j] = v[0];
MyBase::mm[ 4+j] = v[1];
MyBase::mm[ 8+j] = v[2];
MyBase::mm[12+j] = v[3];
}
/// Get jth column, e.g. Vec4f v = m.col(0);
Vec4<T> col(int j) const
{
// assert(j>=0 && j<4);
return Vec4<T>((*this)(0,j), (*this)(1,j), (*this)(2,j), (*this)(3,j));
}
/// Alternative indexed reference to the elements
/// Note that the indices are row first and column second.
/// e.g. m(0,0) = 1;
T& operator()(int i, int j)
{
// assert(i>=0 && i<4);
// assert(j>=0 && j<4);
return MyBase::mm[4*i+j];
}
/// Alternative indexed constant reference to the elements,
/// Note that the indices are row first and column second.
/// e.g. float f = m(1,0);
T operator()(int i, int j) const
{
// assert(i>=0 && i<4);
// assert(j>=0 && j<4);
return MyBase::mm[4*i+j];
}
/// Set the rows of this matrix to the vectors v1, v2, v3, v4
void setRows(const Vec4<T> &v1, const Vec4<T> &v2,
const Vec4<T> &v3, const Vec4<T> &v4)
{
MyBase::mm[ 0] = v1[0];
MyBase::mm[ 1] = v1[1];
MyBase::mm[ 2] = v1[2];
MyBase::mm[ 3] = v1[3];
MyBase::mm[ 4] = v2[0];
MyBase::mm[ 5] = v2[1];
MyBase::mm[ 6] = v2[2];
MyBase::mm[ 7] = v2[3];
MyBase::mm[ 8] = v3[0];
MyBase::mm[ 9] = v3[1];
MyBase::mm[10] = v3[2];
MyBase::mm[11] = v3[3];
MyBase::mm[12] = v4[0];
MyBase::mm[13] = v4[1];
MyBase::mm[14] = v4[2];
MyBase::mm[15] = v4[3];
}
/// Set the columns of this matrix to the vectors v1, v2, v3, v4
void setColumns(const Vec4<T> &v1, const Vec4<T> &v2,
const Vec4<T> &v3, const Vec4<T> &v4)
{
MyBase::mm[ 0] = v1[0];
MyBase::mm[ 1] = v2[0];
MyBase::mm[ 2] = v3[0];
MyBase::mm[ 3] = v4[0];
MyBase::mm[ 4] = v1[1];
MyBase::mm[ 5] = v2[1];
MyBase::mm[ 6] = v3[1];
MyBase::mm[ 7] = v4[1];
MyBase::mm[ 8] = v1[2];
MyBase::mm[ 9] = v2[2];
MyBase::mm[10] = v3[2];
MyBase::mm[11] = v4[2];
MyBase::mm[12] = v1[3];
MyBase::mm[13] = v2[3];
MyBase::mm[14] = v3[3];
MyBase::mm[15] = v4[3];
}
// Set this matrix to zero
void setZero()
{
MyBase::mm[ 0] = 0;
MyBase::mm[ 1] = 0;
MyBase::mm[ 2] = 0;
MyBase::mm[ 3] = 0;
MyBase::mm[ 4] = 0;
MyBase::mm[ 5] = 0;
MyBase::mm[ 6] = 0;
MyBase::mm[ 7] = 0;
MyBase::mm[ 8] = 0;
MyBase::mm[ 9] = 0;
MyBase::mm[10] = 0;
MyBase::mm[11] = 0;
MyBase::mm[12] = 0;
MyBase::mm[13] = 0;
MyBase::mm[14] = 0;
MyBase::mm[15] = 0;
}
/// Set this matrix to identity
void setIdentity()
{
MyBase::mm[ 0] = 1;
MyBase::mm[ 1] = 0;
MyBase::mm[ 2] = 0;
MyBase::mm[ 3] = 0;
MyBase::mm[ 4] = 0;
MyBase::mm[ 5] = 1;
MyBase::mm[ 6] = 0;
MyBase::mm[ 7] = 0;
MyBase::mm[ 8] = 0;
MyBase::mm[ 9] = 0;
MyBase::mm[10] = 1;
MyBase::mm[11] = 0;
MyBase::mm[12] = 0;
MyBase::mm[13] = 0;
MyBase::mm[14] = 0;
MyBase::mm[15] = 1;
}
/// Set upper left to a Mat3
void setMat3(const Mat3<T> &m)
{
for (int i = 0; i < 3; i++)
for (int j=0; j < 3; j++)
MyBase::mm[i*4+j] = m[i][j];
}
Mat3<T> getMat3() const
{
Mat3<T> m;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
m[i][j] = MyBase::mm[i*4+j];
return m;
}
/// Return the translation component
Vec3<T> getTranslation() const
{
return Vec3<T>(MyBase::mm[12], MyBase::mm[13], MyBase::mm[14]);
}
void setTranslation(const Vec3<T> &t)
{
MyBase::mm[12] = t[0];
MyBase::mm[13] = t[1];
MyBase::mm[14] = t[2];
}
/// Assignment operator
template<typename Source>
const Mat4& operator=(const Mat4<Source> &m)
{
const Source *src = m.asPointer();
// don't suppress warnings when assigning from different numerical types
std::copy(src, (src + this->numElements()), MyBase::mm);
return *this;
}
/// Return @c true if this matrix is equivalent to @a m within a tolerance of @a eps.
bool eq(const Mat4 &m, T eps=1.0e-8) const
{
for (int i = 0; i < 16; i++) {
if (!isApproxEqual(MyBase::mm[i], m.mm[i], eps))
return false;
}
return true;
}
/// Negation operator, for e.g. m1 = -m2;
Mat4<T> operator-() const
{
return Mat4<T>(
-MyBase::mm[ 0], -MyBase::mm[ 1], -MyBase::mm[ 2], -MyBase::mm[ 3],
-MyBase::mm[ 4], -MyBase::mm[ 5], -MyBase::mm[ 6], -MyBase::mm[ 7],
-MyBase::mm[ 8], -MyBase::mm[ 9], -MyBase::mm[10], -MyBase::mm[11],
-MyBase::mm[12], -MyBase::mm[13], -MyBase::mm[14], -MyBase::mm[15]
);
} // trivial
/// Multiply each element of this matrix by @a scalar.
template <typename S>
const Mat4<T>& operator*=(S scalar)
{
MyBase::mm[ 0] *= scalar;
MyBase::mm[ 1] *= scalar;
MyBase::mm[ 2] *= scalar;
MyBase::mm[ 3] *= scalar;
MyBase::mm[ 4] *= scalar;
MyBase::mm[ 5] *= scalar;
MyBase::mm[ 6] *= scalar;
MyBase::mm[ 7] *= scalar;
MyBase::mm[ 8] *= scalar;
MyBase::mm[ 9] *= scalar;
MyBase::mm[10] *= scalar;
MyBase::mm[11] *= scalar;
MyBase::mm[12] *= scalar;
MyBase::mm[13] *= scalar;
MyBase::mm[14] *= scalar;
MyBase::mm[15] *= scalar;
return *this;
}
/// Add each element of the given matrix to the corresponding element of this matrix.
template <typename S>
const Mat4<T> &operator+=(const Mat4<S> &m1)
{
const S* s = m1.asPointer();
MyBase::mm[ 0] += s[ 0];
MyBase::mm[ 1] += s[ 1];
MyBase::mm[ 2] += s[ 2];
MyBase::mm[ 3] += s[ 3];
MyBase::mm[ 4] += s[ 4];
MyBase::mm[ 5] += s[ 5];
MyBase::mm[ 6] += s[ 6];
MyBase::mm[ 7] += s[ 7];
MyBase::mm[ 8] += s[ 8];
MyBase::mm[ 9] += s[ 9];
MyBase::mm[10] += s[10];
MyBase::mm[11] += s[11];
MyBase::mm[12] += s[12];
MyBase::mm[13] += s[13];
MyBase::mm[14] += s[14];
MyBase::mm[15] += s[15];
return *this;
}
/// Subtract each element of the given matrix from the corresponding element of this matrix.
template <typename S>
const Mat4<T> &operator-=(const Mat4<S> &m1)
{
const S* s = m1.asPointer();
MyBase::mm[ 0] -= s[ 0];
MyBase::mm[ 1] -= s[ 1];
MyBase::mm[ 2] -= s[ 2];
MyBase::mm[ 3] -= s[ 3];
MyBase::mm[ 4] -= s[ 4];
MyBase::mm[ 5] -= s[ 5];
MyBase::mm[ 6] -= s[ 6];
MyBase::mm[ 7] -= s[ 7];
MyBase::mm[ 8] -= s[ 8];
MyBase::mm[ 9] -= s[ 9];
MyBase::mm[10] -= s[10];
MyBase::mm[11] -= s[11];
MyBase::mm[12] -= s[12];
MyBase::mm[13] -= s[13];
MyBase::mm[14] -= s[14];
MyBase::mm[15] -= s[15];
return *this;
}
/// Multiply this matrix by the given matrix.
template <typename S>
const Mat4<T> &operator*=(const Mat4<S> &m1)
{
Mat4<T> m0(*this);
const T* s0 = m0.asPointer();
const S* s1 = m1.asPointer();
for (int i = 0; i < 4; i++) {
int i4 = 4 * i;
MyBase::mm[i4+0] = static_cast<T>(s0[i4+0] * s1[ 0] +
s0[i4+1] * s1[ 4] +
s0[i4+2] * s1[ 8] +
s0[i4+3] * s1[12]);
MyBase::mm[i4+1] = static_cast<T>(s0[i4+0] * s1[ 1] +
s0[i4+1] * s1[ 5] +
s0[i4+2] * s1[ 9] +
s0[i4+3] * s1[13]);
MyBase::mm[i4+2] = static_cast<T>(s0[i4+0] * s1[ 2] +
s0[i4+1] * s1[ 6] +
s0[i4+2] * s1[10] +
s0[i4+3] * s1[14]);
MyBase::mm[i4+3] = static_cast<T>(s0[i4+0] * s1[ 3] +
s0[i4+1] * s1[ 7] +
s0[i4+2] * s1[11] +
s0[i4+3] * s1[15]);
}
return *this;
}
/// @return transpose of this
Mat4 transpose() const
{
return Mat4<T>(
MyBase::mm[ 0], MyBase::mm[ 4], MyBase::mm[ 8], MyBase::mm[12],
MyBase::mm[ 1], MyBase::mm[ 5], MyBase::mm[ 9], MyBase::mm[13],
MyBase::mm[ 2], MyBase::mm[ 6], MyBase::mm[10], MyBase::mm[14],
MyBase::mm[ 3], MyBase::mm[ 7], MyBase::mm[11], MyBase::mm[15]
);
}
/// @return inverse of this
/// @throw ArithmeticError if singular
Mat4 inverse(T tolerance = 0) const
{
//
// inv [ A | b ] = [ E | f ] A: 3x3, b: 3x1, c': 1x3 d: 1x1
// [ c' | d ] [ g' | h ]
//
// If A is invertible use
//
// E = A^-1 + p*h*r
// p = A^-1 * b
// f = -p * h
// g' = -h * c'
// h = 1 / (d - c'*p)
// r' = c'*A^-1
//
// Otherwise use gauss-jordan elimination
//
//
// We create this alias to ourself so we can easily use own subscript
// operator.
const Mat4<T>& m(*this);
T m0011 = m[0][0] * m[1][1];
T m0012 = m[0][0] * m[1][2];
T m0110 = m[0][1] * m[1][0];
T m0210 = m[0][2] * m[1][0];
T m0120 = m[0][1] * m[2][0];
T m0220 = m[0][2] * m[2][0];
T detA = m0011 * m[2][2] - m0012 * m[2][1] - m0110 * m[2][2]
+ m0210 * m[2][1] + m0120 * m[1][2] - m0220 * m[1][1];
bool hasPerspective =
(!isExactlyEqual(m[0][3], T(0.0)) ||
!isExactlyEqual(m[1][3], T(0.0)) ||
!isExactlyEqual(m[2][3], T(0.0)) ||
!isExactlyEqual(m[3][3], T(1.0)));
T det;
if (hasPerspective) {
det = m[0][3] * det3(m, 1,2,3, 0,2,1)
+ m[1][3] * det3(m, 2,0,3, 0,2,1)
+ m[2][3] * det3(m, 3,0,1, 0,2,1)
+ m[3][3] * detA;
} else {
det = detA * m[3][3];
}
Mat4<T> inv;
bool invertible;
if (isApproxEqual(det,T(0.0),tolerance)) {
invertible = false;
} else if (isApproxEqual(detA,T(0.0),T(1e-8))) {
// det is too small to rely on inversion by subblocks
invertible = m.invert(inv, tolerance);
} else {
invertible = true;
detA = 1.0 / detA;
//
// Calculate A^-1
//
inv[0][0] = detA * ( m[1][1] * m[2][2] - m[1][2] * m[2][1]);
inv[0][1] = detA * (-m[0][1] * m[2][2] + m[0][2] * m[2][1]);
inv[0][2] = detA * ( m[0][1] * m[1][2] - m[0][2] * m[1][1]);
inv[1][0] = detA * (-m[1][0] * m[2][2] + m[1][2] * m[2][0]);
inv[1][1] = detA * ( m[0][0] * m[2][2] - m0220);
inv[1][2] = detA * ( m0210 - m0012);
inv[2][0] = detA * ( m[1][0] * m[2][1] - m[1][1] * m[2][0]);
inv[2][1] = detA * ( m0120 - m[0][0] * m[2][1]);
inv[2][2] = detA * ( m0011 - m0110);
if (hasPerspective) {
//
// Calculate r, p, and h
//
Vec3<T> r;
r[0] = m[3][0] * inv[0][0] + m[3][1] * inv[1][0]
+ m[3][2] * inv[2][0];
r[1] = m[3][0] * inv[0][1] + m[3][1] * inv[1][1]
+ m[3][2] * inv[2][1];
r[2] = m[3][0] * inv[0][2] + m[3][1] * inv[1][2]
+ m[3][2] * inv[2][2];
Vec3<T> p;
p[0] = inv[0][0] * m[0][3] + inv[0][1] * m[1][3]
+ inv[0][2] * m[2][3];
p[1] = inv[1][0] * m[0][3] + inv[1][1] * m[1][3]
+ inv[1][2] * m[2][3];
p[2] = inv[2][0] * m[0][3] + inv[2][1] * m[1][3]
+ inv[2][2] * m[2][3];
T h = m[3][3] - p.dot(Vec3<T>(m[3][0],m[3][1],m[3][2]));
if (isApproxEqual(h,T(0.0),tolerance)) {
invertible = false;
} else {
h = 1.0 / h;
//
// Calculate h, g, and f
//
inv[3][3] = h;
inv[3][0] = -h * r[0];
inv[3][1] = -h * r[1];
inv[3][2] = -h * r[2];
inv[0][3] = -h * p[0];
inv[1][3] = -h * p[1];
inv[2][3] = -h * p[2];
//
// Calculate E
//
p *= h;
inv[0][0] += p[0] * r[0];
inv[0][1] += p[0] * r[1];
inv[0][2] += p[0] * r[2];
inv[1][0] += p[1] * r[0];
inv[1][1] += p[1] * r[1];
inv[1][2] += p[1] * r[2];
inv[2][0] += p[2] * r[0];
inv[2][1] += p[2] * r[1];
inv[2][2] += p[2] * r[2];
}
} else {
// Equations are much simpler in the non-perspective case
inv[3][0] = - (m[3][0] * inv[0][0] + m[3][1] * inv[1][0]
+ m[3][2] * inv[2][0]);
inv[3][1] = - (m[3][0] * inv[0][1] + m[3][1] * inv[1][1]
+ m[3][2] * inv[2][1]);
inv[3][2] = - (m[3][0] * inv[0][2] + m[3][1] * inv[1][2]
+ m[3][2] * inv[2][2]);
inv[0][3] = 0.0;
inv[1][3] = 0.0;
inv[2][3] = 0.0;
inv[3][3] = 1.0;
}
}
if (!invertible) OPENVDB_THROW(ArithmeticError, "Inversion of singular 4x4 matrix");
return inv;
}
/// Determinant of matrix
T det() const
{
const T *ap;
Mat3<T> submat;
T det;
T *sp;
int i, j, k, sign;
det = 0;
sign = 1;
for (i = 0; i < 4; i++) {
ap = &MyBase::mm[ 0];
sp = submat.asPointer();
for (j = 0; j < 4; j++) {
for (k = 0; k < 4; k++) {
if ((k != i) && (j != 0)) {
*sp++ = *ap;
}
ap++;
}
}
det += T(sign) * MyBase::mm[i] * submat.det();
sign = -sign;
}
return det;
}
/// Sets the matrix to a matrix that translates by v
static Mat4 translation(const Vec3d& v)
{
return Mat4(
T(1), T(0), T(0), T(0),
T(0), T(1), T(0), T(0),
T(0), T(0), T(1), T(0),
T(v.x()), T(v.y()),T(v.z()), T(1));
}
/// Sets the matrix to a matrix that translates by v
template <typename T0>
void setToTranslation(const Vec3<T0>& v)
{
MyBase::mm[ 0] = 1;
MyBase::mm[ 1] = 0;
MyBase::mm[ 2] = 0;
MyBase::mm[ 3] = 0;
MyBase::mm[ 4] = 0;
MyBase::mm[ 5] = 1;
MyBase::mm[ 6] = 0;
MyBase::mm[ 7] = 0;
MyBase::mm[ 8] = 0;
MyBase::mm[ 9] = 0;
MyBase::mm[10] = 1;
MyBase::mm[11] = 0;
MyBase::mm[12] = v.x();
MyBase::mm[13] = v.y();
MyBase::mm[14] = v.z();
MyBase::mm[15] = 1;
}
/// Left multiples by the specified translation, i.e. Trans * (*this)
template <typename T0>
void preTranslate(const Vec3<T0>& tr)
{
Vec3<T> tmp(tr.x(), tr.y(), tr.z());
Mat4<T> Tr = Mat4<T>::translation(tmp);
*this = Tr * (*this);
}
/// Right multiplies by the specified translation matrix, i.e. (*this) * Trans
template <typename T0>
void postTranslate(const Vec3<T0>& tr)
{
Vec3<T> tmp(tr.x(), tr.y(), tr.z());
Mat4<T> Tr = Mat4<T>::translation(tmp);
*this = (*this) * Tr;
}
/// Sets the matrix to a matrix that scales by v
template <typename T0>
void setToScale(const Vec3<T0>& v)
{
this->setIdentity();
MyBase::mm[ 0] = v.x();
MyBase::mm[ 5] = v.y();
MyBase::mm[10] = v.z();
}
// Left multiples by the specified scale matrix, i.e. Sc * (*this)
template <typename T0>
void preScale(const Vec3<T0>& v)
{
MyBase::mm[ 0] *= v.x();
MyBase::mm[ 1] *= v.x();
MyBase::mm[ 2] *= v.x();
MyBase::mm[ 3] *= v.x();
MyBase::mm[ 4] *= v.y();
MyBase::mm[ 5] *= v.y();
MyBase::mm[ 6] *= v.y();
MyBase::mm[ 7] *= v.y();
MyBase::mm[ 8] *= v.z();
MyBase::mm[ 9] *= v.z();
MyBase::mm[10] *= v.z();
MyBase::mm[11] *= v.z();
}
// Right multiples by the specified scale matrix, i.e. (*this) * Sc
template <typename T0>
void postScale(const Vec3<T0>& v)
{
MyBase::mm[ 0] *= v.x();
MyBase::mm[ 1] *= v.y();
MyBase::mm[ 2] *= v.z();
MyBase::mm[ 4] *= v.x();
MyBase::mm[ 5] *= v.y();
MyBase::mm[ 6] *= v.z();
MyBase::mm[ 8] *= v.x();
MyBase::mm[ 9] *= v.y();
MyBase::mm[10] *= v.z();
MyBase::mm[12] *= v.x();
MyBase::mm[13] *= v.y();
MyBase::mm[14] *= v.z();
}
/// @brief Sets the matrix to a rotation about the given axis.
/// @param axis The axis (one of X, Y, Z) to rotate about.
/// @param angle The rotation angle, in radians.
void setToRotation(Axis axis, T angle) {*this = rotation<Mat4<T> >(axis, angle);}
/// @brief Sets the matrix to a rotation about an arbitrary axis
/// @param axis The axis of rotation (cannot be zero-length)
/// @param angle The rotation angle, in radians.
void setToRotation(const Vec3<T>& axis, T angle) {*this = rotation<Mat4<T> >(axis, angle);}
/// @brief Sets the matrix to a rotation that maps v1 onto v2 about the cross
/// product of v1 and v2.
void setToRotation(const Vec3<T>& v1, const Vec3<T>& v2) {*this = rotation<Mat4<T> >(v1, v2);}
/// @brief Left multiplies by a rotation clock-wiseabout the given axis into this matrix.
/// @param axis The axis (one of X, Y, Z) of rotation.
/// @param angle The clock-wise rotation angle, in radians.
void preRotate(Axis axis, T angle)
{
T c = static_cast<T>(cos(angle));
T s = -static_cast<T>(sin(angle)); // the "-" makes it clockwise
switch (axis) {
case X_AXIS:
{
T a4, a5, a6, a7;
a4 = c * MyBase::mm[ 4] - s * MyBase::mm[ 8];
a5 = c * MyBase::mm[ 5] - s * MyBase::mm[ 9];
a6 = c * MyBase::mm[ 6] - s * MyBase::mm[10];
a7 = c * MyBase::mm[ 7] - s * MyBase::mm[11];
MyBase::mm[ 8] = s * MyBase::mm[ 4] + c * MyBase::mm[ 8];
MyBase::mm[ 9] = s * MyBase::mm[ 5] + c * MyBase::mm[ 9];
MyBase::mm[10] = s * MyBase::mm[ 6] + c * MyBase::mm[10];
MyBase::mm[11] = s * MyBase::mm[ 7] + c * MyBase::mm[11];
MyBase::mm[ 4] = a4;
MyBase::mm[ 5] = a5;
MyBase::mm[ 6] = a6;
MyBase::mm[ 7] = a7;
}
break;
case Y_AXIS:
{
T a0, a1, a2, a3;
a0 = c * MyBase::mm[ 0] + s * MyBase::mm[ 8];
a1 = c * MyBase::mm[ 1] + s * MyBase::mm[ 9];
a2 = c * MyBase::mm[ 2] + s * MyBase::mm[10];
a3 = c * MyBase::mm[ 3] + s * MyBase::mm[11];
MyBase::mm[ 8] = -s * MyBase::mm[ 0] + c * MyBase::mm[ 8];
MyBase::mm[ 9] = -s * MyBase::mm[ 1] + c * MyBase::mm[ 9];
MyBase::mm[10] = -s * MyBase::mm[ 2] + c * MyBase::mm[10];
MyBase::mm[11] = -s * MyBase::mm[ 3] + c * MyBase::mm[11];
MyBase::mm[ 0] = a0;
MyBase::mm[ 1] = a1;
MyBase::mm[ 2] = a2;
MyBase::mm[ 3] = a3;
}
break;
case Z_AXIS:
{
T a0, a1, a2, a3;
a0 = c * MyBase::mm[ 0] - s * MyBase::mm[ 4];
a1 = c * MyBase::mm[ 1] - s * MyBase::mm[ 5];
a2 = c * MyBase::mm[ 2] - s * MyBase::mm[ 6];
a3 = c * MyBase::mm[ 3] - s * MyBase::mm[ 7];
MyBase::mm[ 4] = s * MyBase::mm[ 0] + c * MyBase::mm[ 4];
MyBase::mm[ 5] = s * MyBase::mm[ 1] + c * MyBase::mm[ 5];
MyBase::mm[ 6] = s * MyBase::mm[ 2] + c * MyBase::mm[ 6];
MyBase::mm[ 7] = s * MyBase::mm[ 3] + c * MyBase::mm[ 7];
MyBase::mm[ 0] = a0;
MyBase::mm[ 1] = a1;
MyBase::mm[ 2] = a2;
MyBase::mm[ 3] = a3;
}
break;
default:
assert(axis==X_AXIS || axis==Y_AXIS || axis==Z_AXIS);
}
}
/// @brief Right multiplies by a rotation clock-wiseabout the given axis into this matrix.
/// @param axis The axis (one of X, Y, Z) of rotation.
/// @param angle The clock-wise rotation angle, in radians.
void postRotate(Axis axis, T angle)
{
T c = static_cast<T>(cos(angle));
T s = -static_cast<T>(sin(angle)); // the "-" makes it clockwise
switch (axis) {
case X_AXIS:
{
T a2, a6, a10, a14;
a2 = c * MyBase::mm[ 2] - s * MyBase::mm[ 1];
a6 = c * MyBase::mm[ 6] - s * MyBase::mm[ 5];
a10 = c * MyBase::mm[10] - s * MyBase::mm[ 9];
a14 = c * MyBase::mm[14] - s * MyBase::mm[13];
MyBase::mm[ 1] = c * MyBase::mm[ 1] + s * MyBase::mm[ 2];
MyBase::mm[ 5] = c * MyBase::mm[ 5] + s * MyBase::mm[ 6];
MyBase::mm[ 9] = c * MyBase::mm[ 9] + s * MyBase::mm[10];
MyBase::mm[13] = c * MyBase::mm[13] + s * MyBase::mm[14];
MyBase::mm[ 2] = a2;
MyBase::mm[ 6] = a6;
MyBase::mm[10] = a10;
MyBase::mm[14] = a14;
}
break;
case Y_AXIS:
{
T a2, a6, a10, a14;
a2 = c * MyBase::mm[ 2] + s * MyBase::mm[ 0];
a6 = c * MyBase::mm[ 6] + s * MyBase::mm[ 4];
a10 = c * MyBase::mm[10] + s * MyBase::mm[ 8];
a14 = c * MyBase::mm[14] + s * MyBase::mm[12];
MyBase::mm[ 0] = c * MyBase::mm[ 0] - s * MyBase::mm[ 2];
MyBase::mm[ 4] = c * MyBase::mm[ 4] - s * MyBase::mm[ 6];
MyBase::mm[ 8] = c * MyBase::mm[ 8] - s * MyBase::mm[10];
MyBase::mm[12] = c * MyBase::mm[12] - s * MyBase::mm[14];
MyBase::mm[ 2] = a2;
MyBase::mm[ 6] = a6;
MyBase::mm[10] = a10;
MyBase::mm[14] = a14;
}
break;
case Z_AXIS:
{
T a1, a5, a9, a13;
a1 = c * MyBase::mm[ 1] - s * MyBase::mm[ 0];
a5 = c * MyBase::mm[ 5] - s * MyBase::mm[ 4];
a9 = c * MyBase::mm[ 9] - s * MyBase::mm[ 8];
a13 = c * MyBase::mm[13] - s * MyBase::mm[12];
MyBase::mm[ 0] = c * MyBase::mm[ 0] + s * MyBase::mm[ 1];
MyBase::mm[ 4] = c * MyBase::mm[ 4] + s * MyBase::mm[ 5];
MyBase::mm[ 8] = c * MyBase::mm[ 8] + s * MyBase::mm[ 9];
MyBase::mm[12] = c * MyBase::mm[12] + s * MyBase::mm[13];
MyBase::mm[ 1] = a1;
MyBase::mm[ 5] = a5;
MyBase::mm[ 9] = a9;
MyBase::mm[13] = a13;
}
break;
default:
assert(axis==X_AXIS || axis==Y_AXIS || axis==Z_AXIS);
}
}
/// @brief Sets the matrix to a shear along axis0 by a fraction of axis1.
/// @param axis0 The fixed axis of the shear.
/// @param axis1 The shear axis.
/// @param shearby The shear factor.
void setToShear(Axis axis0, Axis axis1, T shearby)
{
*this = shear<Mat4<T> >(axis0, axis1, shearby);
}
/// @brief Left multiplies a shearing transformation into the matrix.
/// @see setToShear
void preShear(Axis axis0, Axis axis1, T shear)
{
int index0 = static_cast<int>(axis0);
int index1 = static_cast<int>(axis1);
// to row "index1" add a multiple of the index0 row
MyBase::mm[index1 * 4 + 0] += shear * MyBase::mm[index0 * 4 + 0];
MyBase::mm[index1 * 4 + 1] += shear * MyBase::mm[index0 * 4 + 1];
MyBase::mm[index1 * 4 + 2] += shear * MyBase::mm[index0 * 4 + 2];
MyBase::mm[index1 * 4 + 3] += shear * MyBase::mm[index0 * 4 + 3];
}
/// @brief Right multiplies a shearing transformation into the matrix.
/// @see setToShear
void postShear(Axis axis0, Axis axis1, T shear)
{
int index0 = static_cast<int>(axis0);
int index1 = static_cast<int>(axis1);
// to collumn "index0" add a multiple of the index1 row
MyBase::mm[index0 + 0] += shear * MyBase::mm[index1 + 0];
MyBase::mm[index0 + 4] += shear * MyBase::mm[index1 + 4];
MyBase::mm[index0 + 8] += shear * MyBase::mm[index1 + 8];
MyBase::mm[index0 + 12] += shear * MyBase::mm[index1 + 12];
}
/// Transform a Vec4 by post-multiplication.
template<typename T0>
Vec4<T0> transform(const Vec4<T0> &v) const
{
return static_cast< Vec4<T0> >(v * *this);
}
/// Transform a Vec3 by post-multiplication, without homogenous division.
template<typename T0>
Vec3<T0> transform(const Vec3<T0> &v) const
{
return static_cast< Vec3<T0> >(v * *this);
}
/// Transform a Vec4 by pre-multiplication.
template<typename T0>
Vec4<T0> pretransform(const Vec4<T0> &v) const
{
return static_cast< Vec4<T0> >(*this * v);
}
/// Transform a Vec3 by pre-multiplication, without homogenous division.
template<typename T0>
Vec3<T0> pretransform(const Vec3<T0> &v) const
{
return static_cast< Vec3<T0> >(*this * v);
}
/// Transform a Vec3 by post-multiplication, doing homogenous divison.
template<typename T0>
Vec3<T0> transformH(const Vec3<T0> &p) const
{
T0 w;
// w = p * (*this).col(3);
w = static_cast<T0>(p[0] * MyBase::mm[ 3] + p[1] * MyBase::mm[ 7]
+ p[2] * MyBase::mm[11] + MyBase::mm[15]);
if ( !isExactlyEqual(w , 0.0) ) {
return Vec3<T0>(static_cast<T0>((p[0] * MyBase::mm[ 0] + p[1] * MyBase::mm[ 4] +
p[2] * MyBase::mm[ 8] + MyBase::mm[12]) / w),
static_cast<T0>((p[0] * MyBase::mm[ 1] + p[1] * MyBase::mm[ 5] +
p[2] * MyBase::mm[ 9] + MyBase::mm[13]) / w),
static_cast<T0>((p[0] * MyBase::mm[ 2] + p[1] * MyBase::mm[ 6] +
p[2] * MyBase::mm[10] + MyBase::mm[14]) / w));
}
return Vec3<T0>(0, 0, 0);
}
/// Transform a Vec3 by pre-multiplication, doing homogenous division.
template<typename T0>
Vec3<T0> pretransformH(const Vec3<T0> &p) const
{
T0 w;
// w = p * (*this).col(3);
w = p[0] * MyBase::mm[12] + p[1] * MyBase::mm[13] + p[2] * MyBase::mm[14] + MyBase::mm[15];
if ( !isExactlyEqual(w , 0.0) ) {
return Vec3<T0>(static_cast<T0>((p[0] * MyBase::mm[ 0] + p[1] * MyBase::mm[ 1] +
p[2] * MyBase::mm[ 2] + MyBase::mm[ 3]) / w),
static_cast<T0>((p[0] * MyBase::mm[ 4] + p[1] * MyBase::mm[ 5] +
p[2] * MyBase::mm[ 6] + MyBase::mm[ 7]) / w),
static_cast<T0>((p[0] * MyBase::mm[ 8] + p[1] * MyBase::mm[ 9] +
p[2] * MyBase::mm[10] + MyBase::mm[11]) / w));
}
return Vec3<T0>(0, 0, 0);
}
/// Transform a Vec3 by post-multiplication, without translation.
template<typename T0>
Vec3<T0> transform3x3(const Vec3<T0> &v) const
{
return Vec3<T0>(
static_cast<T0>(v[0] * MyBase::mm[ 0] + v[1] * MyBase::mm[ 4] + v[2] * MyBase::mm[ 8]),
static_cast<T0>(v[0] * MyBase::mm[ 1] + v[1] * MyBase::mm[ 5] + v[2] * MyBase::mm[ 9]),
static_cast<T0>(v[0] * MyBase::mm[ 2] + v[1] * MyBase::mm[ 6] + v[2] * MyBase::mm[10]));
}
private:
bool invert(Mat4<T> &inverse, T tolerance) const;
T det2(const Mat4<T> &a, int i0, int i1, int j0, int j1) const {
int i0row = i0 * 4;
int i1row = i1 * 4;
return a.mm[i0row+j0]*a.mm[i1row+j1] - a.mm[i0row+j1]*a.mm[i1row+j0];
}
T det3(const Mat4<T> &a, int i0, int i1, int i2,
int j0, int j1, int j2) const {
int i0row = i0 * 4;
return a.mm[i0row+j0]*det2(a, i1,i2, j1,j2) +
a.mm[i0row+j1]*det2(a, i1,i2, j2,j0) +
a.mm[i0row+j2]*det2(a, i1,i2, j0,j1);
}
}; // class Mat4
/// @relates Mat4
/// @brief Equality operator, does exact floating point comparisons
template <typename T0, typename T1>
bool operator==(const Mat4<T0> &m0, const Mat4<T1> &m1)
{
const T0 *t0 = m0.asPointer();
const T1 *t1 = m1.asPointer();
for (int i=0; i<16; ++i) if (!isExactlyEqual(t0[i], t1[i])) return false;
return true;
}
/// @relates Mat4
/// @brief Inequality operator, does exact floating point comparisons
template <typename T0, typename T1>
bool operator!=(const Mat4<T0> &m0, const Mat4<T1> &m1) { return !(m0 == m1); }
/// @relates Mat4
/// @brief Multiply each element of the given matrix by @a scalar and return the result.
template <typename S, typename T>
Mat4<typename promote<S, T>::type> operator*(S scalar, const Mat4<T> &m)
{
return m*scalar;
}
/// @relates Mat4
/// @brief Multiply each element of the given matrix by @a scalar and return the result.
template <typename S, typename T>
Mat4<typename promote<S, T>::type> operator*(const Mat4<T> &m, S scalar)
{
Mat4<typename promote<S, T>::type> result(m);
result *= scalar;
return result;
}
/// @relates Mat4
/// @brief Multiply @a _m by @a _v and return the resulting vector.
template<typename T, typename MT>
inline Vec4<typename promote<T, MT>::type>
operator*(const Mat4<MT> &_m,
const Vec4<T> &_v)
{
MT const *m = _m.asPointer();
return Vec4<typename promote<T, MT>::type>(
_v[0]*m[0] + _v[1]*m[1] + _v[2]*m[2] + _v[3]*m[3],
_v[0]*m[4] + _v[1]*m[5] + _v[2]*m[6] + _v[3]*m[7],
_v[0]*m[8] + _v[1]*m[9] + _v[2]*m[10] + _v[3]*m[11],
_v[0]*m[12] + _v[1]*m[13] + _v[2]*m[14] + _v[3]*m[15]);
}
/// @relates Mat4
/// @brief Multiply @a _v by @a _m and return the resulting vector.
template<typename T, typename MT>
inline Vec4<typename promote<T, MT>::type>
operator*(const Vec4<T> &_v,
const Mat4<MT> &_m)
{
MT const *m = _m.asPointer();
return Vec4<typename promote<T, MT>::type>(
_v[0]*m[0] + _v[1]*m[4] + _v[2]*m[8] + _v[3]*m[12],
_v[0]*m[1] + _v[1]*m[5] + _v[2]*m[9] + _v[3]*m[13],
_v[0]*m[2] + _v[1]*m[6] + _v[2]*m[10] + _v[3]*m[14],
_v[0]*m[3] + _v[1]*m[7] + _v[2]*m[11] + _v[3]*m[15]);
}
/// @relates Mat4
/// @brief Multiply @a _m by @a _v and return the resulting vector.
template<typename T, typename MT>
inline Vec3<typename promote<T, MT>::type>
operator*(const Mat4<MT> &_m, const Vec3<T> &_v)
{
MT const *m = _m.asPointer();
return Vec3<typename promote<T, MT>::type>(
_v[0]*m[0] + _v[1]*m[1] + _v[2]*m[2] + m[3],
_v[0]*m[4] + _v[1]*m[5] + _v[2]*m[6] + m[7],
_v[0]*m[8] + _v[1]*m[9] + _v[2]*m[10] + m[11]);
}
/// @relates Mat4
/// @brief Multiply @a _v by @a _m and return the resulting vector.
template<typename T, typename MT>
inline Vec3<typename promote<T, MT>::type>
operator*(const Vec3<T> &_v, const Mat4<MT> &_m)
{
MT const *m = _m.asPointer();
return Vec3<typename promote<T, MT>::type>(
_v[0]*m[0] + _v[1]*m[4] + _v[2]*m[8] + m[12],
_v[0]*m[1] + _v[1]*m[5] + _v[2]*m[9] + m[13],
_v[0]*m[2] + _v[1]*m[6] + _v[2]*m[10] + m[14]);
}
/// @relates Mat4
/// @brief Add corresponding elements of @a m0 and @a m1 and return the result.
template <typename T0, typename T1>
Mat4<typename promote<T0, T1>::type>
operator+(const Mat4<T0> &m0, const Mat4<T1> &m1)
{
Mat4<typename promote<T0, T1>::type> result(m0);
result += m1;
return result;
}
/// @relates Mat4
/// @brief Subtract corresponding elements of @a m0 and @a m1 and return the result.
template <typename T0, typename T1>
Mat4<typename promote<T0, T1>::type>
operator-(const Mat4<T0> &m0, const Mat4<T1> &m1)
{
Mat4<typename promote<T0, T1>::type> result(m0);
result -= m1;
return result;
}
/// @relates Mat4
/// @brief Multiply @a m0 by @a m1 and return the resulting matrix.
template <typename T0, typename T1>
Mat4<typename promote<T0, T1>::type>
operator*(const Mat4<T0> &m0, const Mat4<T1> &m1)
{
Mat4<typename promote<T0, T1>::type> result(m0);
result *= m1;
return result;
}
/// Transform a Vec3 by pre-multiplication, without translation.
/// Presumes this matrix is inverse of coordinate transform
/// Synonymous to "pretransform3x3"
template<typename T0, typename T1>
Vec3<T1> transformNormal(const Mat4<T0> &m, const Vec3<T1> &n)
{
return Vec3<T1>(
static_cast<T1>(m[0][0]*n[0] + m[0][1]*n[1] + m[0][2]*n[2]),
static_cast<T1>(m[1][0]*n[0] + m[1][1]*n[1] + m[1][2]*n[2]),
static_cast<T1>(m[2][0]*n[0] + m[2][1]*n[1] + m[2][2]*n[2]));
}
/// Invert via gauss-jordan elimination. Modified from dreamworks internal mx library
template<typename T>
bool Mat4<T>::invert(Mat4<T> &inverse, T tolerance) const
{
Mat4<T> temp(*this);
inverse.setIdentity();
// Forward elimination step
double det = 1.0;
for (int i = 0; i < 4; ++i) {
int row = i;
double max = fabs(temp[i][i]);
for (int k = i+1; k < 4; ++k) {
if (fabs(temp[k][i]) > max) {
row = k;
max = fabs(temp[k][i]);
}
}
if (isExactlyEqual(max, 0.0)) return false;
// must move pivot to row i
if (row != i) {
det = -det;
for (int k = 0; k < 4; ++k) {
std::swap(temp[row][k], temp[i][k]);
std::swap(inverse[row][k], inverse[i][k]);
}
}
double pivot = temp[i][i];
det *= pivot;
// scale row i
for (int k = 0; k < 4; ++k) {
temp[i][k] /= pivot;
inverse[i][k] /= pivot;
}
// eliminate in rows below i
for (int j = i+1; j < 4; ++j) {
double t = temp[j][i];
if (!isExactlyEqual(t, 0.0)) {
// subtract scaled row i from row j
for (int k = 0; k < 4; ++k) {
temp[j][k] -= temp[i][k] * t;
inverse[j][k] -= inverse[i][k] * t;
}
}
}
}
// Backward elimination step
for (int i = 3; i > 0; --i) {
for (int j = 0; j < i; ++j) {
double t = temp[j][i];
if (!isExactlyEqual(t, 0.0)) {
for (int k = 0; k < 4; ++k) {
inverse[j][k] -= inverse[i][k]*t;
}
}
}
}
return det*det >= tolerance*tolerance;
}
template <typename T>
inline bool isAffine(const Mat4<T>& m) {
return (m.col(3) == Vec4<T>(0, 0, 0, 1));
}
template <typename T>
inline bool hasTranslation(const Mat4<T>& m) {
return (m.row(3) != Vec4<T>(0, 0, 0, 1));
}
template<typename T>
inline Mat4<T>
Abs(const Mat4<T>& m)
{
Mat4<T> out;
const T* ip = m.asPointer();
T* op = out.asPointer();
for (unsigned i = 0; i < 16; ++i, ++op, ++ip) *op = math::Abs(*ip);
return out;
}
template<typename Type1, typename Type2>
inline Mat4<Type1>
cwiseAdd(const Mat4<Type1>& m, const Type2 s)
{
Mat4<Type1> out;
const Type1* ip = m.asPointer();
Type1* op = out.asPointer();
for (unsigned i = 0; i < 16; ++i, ++op, ++ip) {
OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN
*op = *ip + s;
OPENVDB_NO_TYPE_CONVERSION_WARNING_END
}
return out;
}
template<typename T>
inline bool
cwiseLessThan(const Mat4<T>& m0, const Mat4<T>& m1)
{
return cwiseLessThan<4, T>(m0, m1);
}
template<typename T>
inline bool
cwiseGreaterThan(const Mat4<T>& m0, const Mat4<T>& m1)
{
return cwiseGreaterThan<4, T>(m0, m1);
}
using Mat4s = Mat4<float>;
using Mat4d = Mat4<double>;
using Mat4f = Mat4d;
OPENVDB_IS_POD(Mat4s)
OPENVDB_IS_POD(Mat4d)
} // namespace math
template<> inline math::Mat4s zeroVal<math::Mat4s>() { return math::Mat4s::zero(); }
template<> inline math::Mat4d zeroVal<math::Mat4d>() { return math::Mat4d::zero(); }
} // namespace OPENVDB_VERSION_NAME
} // namespace openvdb
#endif // OPENVDB_UTIL_MAT4_H_HAS_BEEN_INCLUDED
Exceptions.h
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
Mat3.h
Math.h
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
OPENVDB_IS_POD
#define OPENVDB_IS_POD(Type)
Definition Math.h:56
Platform.h
OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN
#define OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN
Bracket code with OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN/_END, to inhibit warnings about type conve...
Definition Platform.h:227
OPENVDB_NO_TYPE_CONVERSION_WARNING_END
#define OPENVDB_NO_TYPE_CONVERSION_WARNING_END
Definition Platform.h:228
Vec3.h
Vec4.h
openvdb::v11_0::ArithmeticError
Definition Exceptions.h:56
openvdb::v11_0::math::Mat3
3x3 matrix class.
Definition Mat3.h:29
openvdb::v11_0::math::Mat3::det
T det() const
Determinant of matrix.
Definition Mat3.h:479
openvdb::v11_0::math::Mat4
4x4 -matrix class.
Definition Mat4.h:31
openvdb::v11_0::math::Mat4::postTranslate
void postTranslate(const Vec3< T0 > &tr)
Right multiplies by the specified translation matrix, i.e. (*this) * Trans.
Definition Mat4.h:714
openvdb::v11_0::math::Mat4::Mat4
Mat4()=default
openvdb::v11_0::math::Mat4::preScale
void preScale(const Vec3< T0 > &v)
Definition Mat4.h:736
openvdb::v11_0::math::Mat4::operator+
Mat4< typename promote< T0, T1 >::type > operator+(const Mat4< T0 > &m0, const Mat4< T1 > &m1)
Add corresponding elements of m0 and m1 and return the result.
Definition Mat4.h:1192
openvdb::v11_0::math::Mat4::operator*=
const Mat4< T > & operator*=(const Mat4< S > &m1)
Multiply this matrix by the given matrix.
Definition Mat4.h:439
openvdb::v11_0::math::Mat4::getTranslation
Vec3< T > getTranslation() const
Return the translation component.
Definition Mat4.h:309
openvdb::v11_0::math::Mat4::Mat4
Mat4(const Mat4< Source > &m)
Conversion constructor.
Definition Mat4.h:107
openvdb::v11_0::math::Mat4::preTranslate
void preTranslate(const Vec3< T0 > &tr)
Left multiples by the specified translation, i.e. Trans * (*this)
Definition Mat4.h:703
openvdb::v11_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:878
openvdb::v11_0::math::Mat4::setIdentity
void setIdentity()
Set this matrix to identity.
Definition Mat4.h:265
openvdb::v11_0::math::Mat4::operator*
Mat4< typename promote< S, T >::type > operator*(const Mat4< T > &m, S scalar)
Multiply each element of the given matrix by scalar and return the result.
Definition Mat4.h:1125
openvdb::v11_0::math::Mat4::operator*
Vec4< typename promote< T, MT >::type > operator*(const Vec4< T > &_v, const Mat4< MT > &_m)
Multiply _v by _m and return the resulting vector.
Definition Mat4.h:1151
openvdb::v11_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:788
openvdb::v11_0::math::Mat4< Real >::setRows
void setRows(const Vec4< Real > &v1, const Vec4< Real > &v2, const Vec4< Real > &v3, const Vec4< Real > &v4)
Definition Mat4.h:194
openvdb::v11_0::math::Mat4::setZero
void setZero()
Definition Mat4.h:244
openvdb::v11_0::math::Mat4::setToScale
void setToScale(const Vec3< T0 > &v)
Sets the matrix to a matrix that scales by v.
Definition Mat4.h:726
openvdb::v11_0::math::Mat4::inverse
Mat4 inverse(T tolerance=0) const
Definition Mat4.h:485
openvdb::v11_0::math::Mat4::translation
static Mat4 translation(const Vec3d &v)
Sets the matrix to a matrix that translates by v.
Definition Mat4.h:667
openvdb::v11_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:798
openvdb::v11_0::math::Mat4::getMat3
Mat3< T > getMat3() const
Definition Mat4.h:297
openvdb::v11_0::math::Mat4::col
Vec4< T > col(int j) const
Get jth column, e.g. Vec4f v = m.col(0);.
Definition Mat4.h:167
openvdb::v11_0::math::Mat4::identity
static const Mat4< T > & identity()
Predefined constant for identity matrix.
Definition Mat4.h:117
openvdb::v11_0::math::Mat4::eq
bool eq(const Mat4 &m, T eps=1.0e-8) const
Return true if this matrix is equivalent to m within a tolerance of eps.
Definition Mat4.h:333
openvdb::v11_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:960
openvdb::v11_0::math::Mat4::pretransform
Vec3< T0 > pretransform(const Vec3< T0 > &v) const
Transform a Vec3 by pre-multiplication, without homogenous division.
Definition Mat4.h:1019
openvdb::v11_0::math::Mat4::transpose
Mat4 transpose() const
Definition Mat4.h:472
openvdb::v11_0::math::Mat4::postShear
void postShear(Axis axis0, Axis axis1, T shear)
Right multiplies a shearing transformation into the matrix.
Definition Mat4.h:983
openvdb::v11_0::math::Mat4::operator==
bool operator==(const Mat4< T0 > &m0, const Mat4< T1 > &m1)
Equality operator, does exact floating point comparisons.
Definition Mat4.h:1100
openvdb::v11_0::math::Mat4::setToRotation
void setToRotation(Axis axis, T angle)
Sets the matrix to a rotation about the given axis.
Definition Mat4.h:783
openvdb::v11_0::math::Mat4::setCol
void setCol(int j, const Vec4< T > &v)
Set jth column to vector v.
Definition Mat4.h:157
openvdb::v11_0::math::Mat4::operator*
Vec3< typename promote< T, MT >::type > operator*(const Mat4< MT > &_m, const Vec3< T > &_v)
Multiply _m by _v and return the resulting vector.
Definition Mat4.h:1166
openvdb::v11_0::math::Mat4::operator*
Vec3< typename promote< T, MT >::type > operator*(const Vec3< T > &_v, const Mat4< MT > &_m)
Multiply _v by _m and return the resulting vector.
Definition Mat4.h:1179
openvdb::v11_0::math::Mat4::transform
Vec4< T0 > transform(const Vec4< T0 > &v) const
Transform a Vec4 by post-multiplication.
Definition Mat4.h:998
openvdb::v11_0::math::Mat4::preShear
void preShear(Axis axis0, Axis axis1, T shear)
Left multiplies a shearing transformation into the matrix.
Definition Mat4.h:968
openvdb::v11_0::math::Mat4< Real >::setColumns
void setColumns(const Vec4< Real > &v1, const Vec4< Real > &v2, const Vec4< Real > &v3, const Vec4< Real > &v4)
Definition Mat4.h:219
openvdb::v11_0::math::Mat4< Real >::MyBase
Mat< 4, Real > MyBase
Definition Mat4.h:36
openvdb::v11_0::math::Mat4::zero
static const Mat4< T > & zero()
Predefined constant for zero matrix.
Definition Mat4.h:128
openvdb::v11_0::math::Mat4::transform3x3
Vec3< T0 > transform3x3(const Vec3< T0 > &v) const
Transform a Vec3 by post-multiplication, without translation.
Definition Mat4.h:1069
openvdb::v11_0::math::Mat4::Mat4
Mat4(const Vec4< Source > &v1, const Vec4< Source > &v2, const Vec4< Source > &v3, const Vec4< Source > &v4, bool rows=true)
Definition Mat4.h:95
openvdb::v11_0::math::Mat4::setTranslation
void setTranslation(const Vec3< T > &t)
Definition Mat4.h:314
openvdb::v11_0::math::Mat4::pretransformH
Vec3< T0 > pretransformH(const Vec3< T0 > &p) const
Transform a Vec3 by pre-multiplication, doing homogenous division.
Definition Mat4.h:1048
openvdb::v11_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:792
openvdb::v11_0::math::Mat4::setToTranslation
void setToTranslation(const Vec3< T0 > &v)
Sets the matrix to a matrix that translates by v.
Definition Mat4.h:678
openvdb::v11_0::math::Mat4< Real >::det
Real det() const
Definition Mat4.h:637
openvdb::v11_0::math::Mat4::operator*
Mat4< typename promote< S, T >::type > operator*(S scalar, const Mat4< T > &m)
Multiply each element of the given matrix by scalar and return the result.
Definition Mat4.h:1117
openvdb::v11_0::math::Mat4::row
Vec4< T > row(int i) const
Get ith row, e.g. Vec4f v = m.row(1);.
Definition Mat4.h:150
openvdb::v11_0::math::Mat4::operator+=
const Mat4< T > & operator+=(const Mat4< S > &m1)
Add each element of the given matrix to the corresponding element of this matrix.
Definition Mat4.h:381
openvdb::v11_0::math::Mat4::operator-
Mat4< typename promote< T0, T1 >::type > operator-(const Mat4< T0 > &m0, const Mat4< T1 > &m1)
Subtract corresponding elements of m0 and m1 and return the result.
Definition Mat4.h:1203
openvdb::v11_0::math::Mat4::Mat4
Mat4(Source *a)
Constructor given array of elements, the ordering is in row major form:
Definition Mat4.h:51
openvdb::v11_0::math::Mat4::operator!=
bool operator!=(const Mat4< T0 > &m0, const Mat4< T1 > &m1)
Inequality operator, does exact floating point comparisons.
Definition Mat4.h:1112
openvdb::v11_0::math::Mat4::operator()
T & operator()(int i, int j)
Definition Mat4.h:176
openvdb::v11_0::math::Mat4::setRow
void setRow(int i, const Vec4< T > &v)
Set ith row to vector v.
Definition Mat4.h:139
openvdb::v11_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:66
openvdb::v11_0::math::Mat4::postScale
void postScale(const Vec3< T0 > &v)
Definition Mat4.h:758
openvdb::v11_0::math::Mat4::transform
Vec3< T0 > transform(const Vec3< T0 > &v) const
Transform a Vec3 by post-multiplication, without homogenous division.
Definition Mat4.h:1005
openvdb::v11_0::math::Mat4::operator*
Mat4< typename promote< T0, T1 >::type > operator*(const Mat4< T0 > &m0, const Mat4< T1 > &m1)
Multiply m0 by m1 and return the resulting matrix.
Definition Mat4.h:1214
openvdb::v11_0::math::Mat4::operator()
T operator()(int i, int j) const
Definition Mat4.h:186
openvdb::v11_0::math::Mat4::operator-=
const Mat4< T > & operator-=(const Mat4< S > &m1)
Subtract each element of the given matrix from the corresponding element of this matrix.
Definition Mat4.h:410
openvdb::v11_0::math::Mat4::transformH
Vec3< T0 > transformH(const Vec3< T0 > &p) const
Transform a Vec3 by post-multiplication, doing homogenous divison.
Definition Mat4.h:1026
openvdb::v11_0::math::Mat4::setMat3
void setMat3(const Mat3< T > &m)
Set upper left to a Mat3.
Definition Mat4.h:290
openvdb::v11_0::math::Mat4::pretransform
Vec4< T0 > pretransform(const Vec4< T0 > &v) const
Transform a Vec4 by pre-multiplication.
Definition Mat4.h:1012
openvdb::v11_0::math::Mat4::operator=
const Mat4 & operator=(const Mat4< Source > &m)
Assignment operator.
Definition Mat4.h:323
openvdb::v11_0::math::Mat4::operator*=
const Mat4< T > & operator*=(S scalar)
Multiply each element of this matrix by scalar.
Definition Mat4.h:355
openvdb::v11_0::math::Mat4< Real >::ValueType
Real ValueType
Definition Mat4.h:35
openvdb::v11_0::math::Mat4::operator*
Vec4< typename promote< T, MT >::type > operator*(const Mat4< MT > &_m, const Vec4< T > &_v)
Multiply _m by _v and return the resulting vector.
Definition Mat4.h:1136
openvdb::v11_0::math::Mat4< Real >::value_type
Real value_type
Definition Mat4.h:34
openvdb::v11_0::math::Mat4::operator-
Mat4< T > operator-() const
Negation operator, for e.g. m1 = -m2;.
Definition Mat4.h:343
openvdb::v11_0::math::Mat::mm
T mm[SIZE *SIZE]
Definition Mat.h:160
openvdb::v11_0::math::Mat< 4, T >::Mat
Mat()=default
openvdb::v11_0::math::Mat::asPointer
T * asPointer()
Direct access to the internal data.
Definition Mat.h:101
openvdb::v11_0::math::Mat4< Real >::numElements
static unsigned numElements()
Definition Mat.h:41
openvdb::v11_0::math::Vec3
Definition Vec3.h:24
openvdb::v11_0::math::Vec3::x
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition Vec3.h:85
openvdb::v11_0::math::Vec3::dot
T dot(const Vec3< T > &v) const
Dot product.
Definition Vec3.h:191
openvdb::v11_0::math::Vec3::y
T & y()
Definition Vec3.h:86
openvdb::v11_0::math::Vec3::z
T & z()
Definition Vec3.h:87
openvdb::v11_0::math::Vec4
Definition Vec4.h:25
openvdb::v11_0::math::mat3_internal::pivot
void pivot(int i, int j, Mat3< T > &S, Vec3< T > &D, Mat3< T > &Q)
Definition Mat3.h:668
openvdb::v11_0::math::transformNormal
Vec3< T1 > transformNormal(const Mat4< T0 > &m, const Vec3< T1 > &n)
Definition Mat4.h:1226
openvdb::v11_0::math::hasTranslation
bool hasTranslation(const Mat4< T > &m)
Definition Mat4.h:1309
openvdb::v11_0::math::Mat4s
Mat4< float > Mat4s
Definition Mat4.h:1353
openvdb::v11_0::math::cwiseLessThan
bool cwiseLessThan(const Mat< SIZE, T > &m0, const Mat< SIZE, T > &m1)
Definition Mat.h:1015
openvdb::v11_0::math::Mat4f
Mat4d Mat4f
Definition Mat4.h:1355
openvdb::v11_0::math::isApproxEqual
bool isApproxEqual(const Type &a, const Type &b, const Type &tolerance)
Return true if a is equal to b to within the given tolerance.
Definition Math.h:406
openvdb::v11_0::math::cwiseAdd
Mat3< Type1 > cwiseAdd(const Mat3< Type1 > &m, const Type2 s)
Definition Mat3.h:806
openvdb::v11_0::math::Vec3d
Vec3< double > Vec3d
Definition Vec3.h:664
openvdb::v11_0::math::isAffine
bool isAffine(const Mat4< T > &m)
Definition Mat4.h:1304
openvdb::v11_0::math::rotation
MatType rotation(const Quat< typename MatType::value_type > &q, typename MatType::value_type eps=static_cast< typename MatType::value_type >(1.0e-8))
Return the rotation matrix specified by the given quaternion.
Definition Mat.h:172
openvdb::v11_0::math::Abs
Coord Abs(const Coord &xyz)
Definition Coord.h:517
openvdb::v11_0::math::Mat4d
Mat4< double > Mat4d
Definition Mat4.h:1354
openvdb::v11_0::math::angle
T angle(const Vec2< T > &v1, const Vec2< T > &v2)
Definition Vec2.h:446
openvdb::v11_0::math::isExactlyEqual
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition Math.h:443
openvdb::v11_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:688
openvdb::v11_0::math::Axis
Axis
Definition Math.h:901
openvdb::v11_0::math::Z_AXIS
@ Z_AXIS
Definition Math.h:904
openvdb::v11_0::math::X_AXIS
@ X_AXIS
Definition Math.h:902
openvdb::v11_0::math::Y_AXIS
@ Y_AXIS
Definition Math.h:903
openvdb::v11_0::math::cwiseGreaterThan
bool cwiseGreaterThan(const Mat< SIZE, T > &m0, const Mat< SIZE, T > &m1)
Definition Mat.h:1029
openvdb::v11_0::zeroVal
constexpr T zeroVal()
Return the value of type T that corresponds to zero.
Definition Math.h:70
openvdb
Definition Exceptions.h:13
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:212