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