1 // 2 // Copyright 2016 Pixar 3 // 4 // Licensed under the Apache License, Version 2.0 (the "Apache License") 5 // with the following modification; you may not use this file except in 6 // compliance with the Apache License and the following modification to it: 7 // Section 6. Trademarks. is deleted and replaced with: 8 // 9 // 6. Trademarks. This License does not grant permission to use the trade 10 // names, trademarks, service marks, or product names of the Licensor 11 // and its affiliates, except as required to comply with Section 4(c) of 12 // the License and to reproduce the content of the NOTICE file. 13 // 14 // You may obtain a copy of the Apache License at 15 // 16 // http://www.apache.org/licenses/LICENSE-2.0 17 // 18 // Unless required by applicable law or agreed to in writing, software 19 // distributed under the Apache License with the above modification is 20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 21 // KIND, either express or implied. See the Apache License for the specific 22 // language governing permissions and limitations under the Apache License. 23 // 24 //////////////////////////////////////////////////////////////////////// 25 // This file is generated by a script. Do not edit directly. Edit the 26 // matrix3.template.h file to make changes. 27 28 #ifndef PXR_BASE_GF_MATRIX3D_H 29 #define PXR_BASE_GF_MATRIX3D_H 30 31 /// \file gf/matrix3d.h 32 /// \ingroup group_gf_LinearAlgebra 33 34 #include "pxr/pxr.h" 35 #include "pxr/base/gf/api.h" 36 #include "pxr/base/gf/declare.h" 37 #include "pxr/base/gf/matrixData.h" 38 #include "pxr/base/gf/vec3d.h" 39 #include "pxr/base/gf/traits.h" 40 41 #include <boost/functional/hash.hpp> 42 43 #include <iosfwd> 44 #include <vector> 45 46 PXR_NAMESPACE_OPEN_SCOPE 47 48 template <> 49 struct GfIsGfMatrix<class GfMatrix3d> { static const bool value = true; }; 50 51 class GfMatrix3d; 52 class GfMatrix3f; 53 class GfRotation; 54 class GfQuaternion; 55 class GfQuatd; 56 57 /// \class GfMatrix3d 58 /// \ingroup group_gf_LinearAlgebra 59 /// 60 /// Stores a 3x3 matrix of \c double elements. A basic type. 61 /// 62 /// Matrices are defined to be in row-major order, so <c>matrix[i][j]</c> 63 /// indexes the element in the \e i th row and the \e j th column. 64 /// 65 /// <h3>3D Transformations</h3> 66 /// 67 /// Three methods, SetRotate(), SetScale(), and ExtractRotation(), interpret 68 /// a GfMatrix3d as a 3D transformation. By convention, vectors are treated 69 /// primarily as row vectors, implying the following: 70 /// 71 /// \li Transformation matrices are organized to deal with row 72 /// vectors, not column vectors. 73 /// \li Each of the Set() methods in this class completely rewrites the 74 /// matrix; for example, SetRotate() yields a matrix 75 /// which does nothing but rotate. 76 /// \li When multiplying two transformation matrices, the matrix 77 /// on the left applies a more local transformation to a row 78 /// vector. For example, if R represents a rotation 79 /// matrix and S represents a scale matrix, the 80 /// product R*S will rotate a row vector, then scale 81 /// it. 82 class GfMatrix3d 83 { 84 public: 85 typedef double ScalarType; 86 87 static const size_t numRows = 3; 88 static const size_t numColumns = 3; 89 90 /// Default constructor. Leaves the matrix component values undefined. 91 GfMatrix3d() = default; 92 93 /// Constructor. Initializes the matrix from 9 independent 94 /// \c double values, specified in row-major order. For example, 95 /// parameter \e m10 specifies the value in row 1 and column 0. 96 GfMatrix3d(double m00, double m01, double m02, 97 double m10, double m11, double m12, 98 double m20, double m21, double m22) { 99 Set(m00, m01, m02, 100 m10, m11, m12, 101 m20, m21, m22); 102 } 103 104 /// Constructor. Initializes the matrix from a 3x3 array 105 /// of \c double values, specified in row-major order. 106 GfMatrix3d(const double m[3][3]) { 107 Set(m); 108 } 109 110 /// Constructor. Explicitly initializes the matrix to \e s times the 111 /// identity matrix. 112 explicit GfMatrix3d(double s) { 113 SetDiagonal(s); 114 } 115 116 /// This explicit constructor initializes the matrix to \p s times 117 /// the identity matrix. 118 explicit GfMatrix3d(int s) { 119 SetDiagonal(s); 120 } 121 122 /// Constructor. Explicitly initializes the matrix to diagonal form, 123 /// with the \e i th element on the diagonal set to <c>v[i]</c>. 124 explicit GfMatrix3d(const GfVec3d& v) { 125 SetDiagonal(v); 126 } 127 128 /// Constructor. Initialize the matrix from a vector of vectors of 129 /// double. The vector is expected to be 3x3. If it is 130 /// too big, only the first 3 rows and/or columns will be used. 131 /// If it is too small, uninitialized elements will be filled in with 132 /// the corresponding elements from an identity matrix. 133 /// 134 GF_API 135 explicit GfMatrix3d(const std::vector< std::vector<double> >& v); 136 137 /// Constructor. Initialize the matrix from a vector of vectors of 138 /// float. The vector is expected to be 3x3. If it is 139 /// too big, only the first 3 rows and/or columns will be used. 140 /// If it is too small, uninitialized elements will be filled in with 141 /// the corresponding elements from an identity matrix. 142 /// 143 GF_API 144 explicit GfMatrix3d(const std::vector< std::vector<float> >& v); 145 146 /// Constructor. Initialize matrix from rotation. 147 GF_API 148 GfMatrix3d(const GfRotation& rot); 149 150 /// Constructor. Initialize matrix from a quaternion. 151 GF_API 152 explicit GfMatrix3d(const GfQuatd& rot); 153 154 /// This explicit constructor converts a "float" matrix to a "double" matrix. 155 GF_API 156 explicit GfMatrix3d(const class GfMatrix3f& m); 157 158 /// Sets a row of the matrix from a Vec3. 159 void SetRow(int i, const GfVec3d & v) { 160 _mtx[i][0] = v[0]; 161 _mtx[i][1] = v[1]; 162 _mtx[i][2] = v[2]; 163 } 164 165 /// Sets a column of the matrix from a Vec3. 166 void SetColumn(int i, const GfVec3d & v) { 167 _mtx[0][i] = v[0]; 168 _mtx[1][i] = v[1]; 169 _mtx[2][i] = v[2]; 170 } 171 172 /// Gets a row of the matrix as a Vec3. 173 GfVec3d GetRow(int i) const { 174 return GfVec3d(_mtx[i][0], _mtx[i][1], _mtx[i][2]); 175 } 176 177 /// Gets a column of the matrix as a Vec3. 178 GfVec3d GetColumn(int i) const { 179 return GfVec3d(_mtx[0][i], _mtx[1][i], _mtx[2][i]); 180 } 181 182 /// Sets the matrix from 9 independent \c double values, 183 /// specified in row-major order. For example, parameter \e m10 specifies 184 /// the value in row 1 and column 0. 185 GfMatrix3d& Set(double m00, double m01, double m02, 186 double m10, double m11, double m12, 187 double m20, double m21, double m22) { 188 _mtx[0][0] = m00; _mtx[0][1] = m01; _mtx[0][2] = m02; 189 _mtx[1][0] = m10; _mtx[1][1] = m11; _mtx[1][2] = m12; 190 _mtx[2][0] = m20; _mtx[2][1] = m21; _mtx[2][2] = m22; 191 return *this; 192 } 193 194 /// Sets the matrix from a 3x3 array of \c double 195 /// values, specified in row-major order. 196 GfMatrix3d& Set(const double m[3][3]) { 197 _mtx[0][0] = m[0][0]; 198 _mtx[0][1] = m[0][1]; 199 _mtx[0][2] = m[0][2]; 200 _mtx[1][0] = m[1][0]; 201 _mtx[1][1] = m[1][1]; 202 _mtx[1][2] = m[1][2]; 203 _mtx[2][0] = m[2][0]; 204 _mtx[2][1] = m[2][1]; 205 _mtx[2][2] = m[2][2]; 206 return *this; 207 } 208 209 /// Sets the matrix to the identity matrix. 210 GfMatrix3d& SetIdentity() { 211 return SetDiagonal(1); 212 } 213 214 /// Sets the matrix to zero. 215 GfMatrix3d& SetZero() { 216 return SetDiagonal(0); 217 } 218 219 /// Sets the matrix to \e s times the identity matrix. 220 GF_API 221 GfMatrix3d& SetDiagonal(double s); 222 223 /// Sets the matrix to have diagonal (<c>v[0], v[1], v[2]</c>). 224 GF_API 225 GfMatrix3d& SetDiagonal(const GfVec3d&); 226 227 /// Fills a 3x3 array of \c double values with the values in 228 /// the matrix, specified in row-major order. 229 GF_API 230 double* Get(double m[3][3]) const; 231 232 /// Returns raw access to components of matrix as an array of 233 /// \c double values. Components are in row-major order. 234 double* data() { 235 return _mtx.GetData(); 236 } 237 238 /// Returns const raw access to components of matrix as an array of 239 /// \c double values. Components are in row-major order. 240 const double* data() const { 241 return _mtx.GetData(); 242 } 243 244 /// Returns vector components as an array of \c double values. 245 double* GetArray() { 246 return _mtx.GetData(); 247 } 248 249 /// Returns vector components as a const array of \c double values. 250 const double* GetArray() const { 251 return _mtx.GetData(); 252 } 253 254 /// Accesses an indexed row \e i of the matrix as an array of 3 \c 255 /// double values so that standard indexing (such as <c>m[0][1]</c>) 256 /// works correctly. 257 double* operator [](int i) { return _mtx[i]; } 258 259 /// Accesses an indexed row \e i of the matrix as an array of 3 \c 260 /// double values so that standard indexing (such as <c>m[0][1]</c>) 261 /// works correctly. 262 const double* operator [](int i) const { return _mtx[i]; } 263 264 /// Hash. 265 friend inline size_t hash_value(GfMatrix3d const &m) { 266 int nElems = 3 * 3; 267 size_t h = 0; 268 const double *p = m.GetArray(); 269 while (nElems--) 270 boost::hash_combine(h, *p++); 271 return h; 272 } 273 274 /// Tests for element-wise matrix equality. All elements must match 275 /// exactly for matrices to be considered equal. 276 GF_API 277 bool operator ==(const GfMatrix3d& m) const; 278 279 /// Tests for element-wise matrix equality. All elements must match 280 /// exactly for matrices to be considered equal. 281 GF_API 282 bool operator ==(const GfMatrix3f& m) const; 283 284 /// Tests for element-wise matrix inequality. All elements must match 285 /// exactly for matrices to be considered equal. 286 bool operator !=(const GfMatrix3d& m) const { 287 return !(*this == m); 288 } 289 290 /// Tests for element-wise matrix inequality. All elements must match 291 /// exactly for matrices to be considered equal. 292 bool operator !=(const GfMatrix3f& m) const { 293 return !(*this == m); 294 } 295 296 /// Returns the transpose of the matrix. 297 GF_API 298 GfMatrix3d GetTranspose() const; 299 300 /// Returns the inverse of the matrix, or FLT_MAX * SetIdentity() if the 301 /// matrix is singular. (FLT_MAX is the largest value a \c float can have, 302 /// as defined by the system.) The matrix is considered singular if the 303 /// determinant is less than or equal to the optional parameter \e eps. If 304 /// \e det is non-null, <c>*det</c> is set to the determinant. 305 GF_API 306 GfMatrix3d GetInverse(double* det = NULL, double eps = 0) const; 307 308 /// Returns the determinant of the matrix. 309 GF_API 310 double GetDeterminant() const; 311 312 /// Makes the matrix orthonormal in place. This is an iterative method that 313 /// is much more stable than the previous cross/cross method. If the 314 /// iterative method does not converge, a warning is issued. 315 /// 316 /// Returns true if the iteration converged, false otherwise. Leaves any 317 /// translation part of the matrix unchanged. If \a issueWarning is true, 318 /// this method will issue a warning if the iteration does not converge, 319 /// otherwise it will be silent. 320 GF_API 321 bool Orthonormalize(bool issueWarning=true); 322 323 /// Returns an orthonormalized copy of the matrix. 324 GF_API 325 GfMatrix3d GetOrthonormalized(bool issueWarning=true) const; 326 327 /// Returns the sign of the determinant of the matrix, i.e. 1 for a 328 /// right-handed matrix, -1 for a left-handed matrix, and 0 for a 329 /// singular matrix. 330 GF_API 331 double GetHandedness() const; 332 333 /// Returns true if the vectors in the matrix form a right-handed 334 /// coordinate system. 335 bool IsRightHanded() const { 336 return GetHandedness() == 1.0; 337 } 338 339 /// Returns true if the vectors in matrix form a left-handed 340 /// coordinate system. 341 bool IsLeftHanded() const { 342 return GetHandedness() == -1.0; 343 } 344 345 /// Post-multiplies matrix \e m into this matrix. 346 GF_API 347 GfMatrix3d& operator *=(const GfMatrix3d& m); 348 349 /// Multiplies the matrix by a double. 350 GF_API 351 GfMatrix3d& operator *=(double); 352 353 /// Returns the product of a matrix and a double. 354 friend GfMatrix3d operator *(const GfMatrix3d& m1, double d) 355 { 356 GfMatrix3d m = m1; 357 return m *= d; 358 } 359 360 /// 361 // Returns the product of a matrix and a double. 362 friend GfMatrix3d operator *(double d, const GfMatrix3d& m) 363 { 364 return m * d; 365 } 366 367 /// Adds matrix \e m to this matrix. 368 GF_API 369 GfMatrix3d& operator +=(const GfMatrix3d& m); 370 371 /// Subtracts matrix \e m from this matrix. 372 GF_API 373 GfMatrix3d& operator -=(const GfMatrix3d& m); 374 375 /// Returns the unary negation of matrix \e m. 376 GF_API 377 friend GfMatrix3d operator -(const GfMatrix3d& m); 378 379 /// Adds matrix \e m2 to \e m1 380 friend GfMatrix3d operator +(const GfMatrix3d& m1, const GfMatrix3d& m2) 381 { 382 GfMatrix3d tmp(m1); 383 tmp += m2; 384 return tmp; 385 } 386 387 /// Subtracts matrix \e m2 from \e m1. 388 friend GfMatrix3d operator -(const GfMatrix3d& m1, const GfMatrix3d& m2) 389 { 390 GfMatrix3d tmp(m1); 391 tmp -= m2; 392 return tmp; 393 } 394 395 /// Multiplies matrix \e m1 by \e m2. 396 friend GfMatrix3d operator *(const GfMatrix3d& m1, const GfMatrix3d& m2) 397 { 398 GfMatrix3d tmp(m1); 399 tmp *= m2; 400 return tmp; 401 } 402 403 /// Divides matrix \e m1 by \e m2 (that is, <c>m1 * inv(m2)</c>). 404 friend GfMatrix3d operator /(const GfMatrix3d& m1, const GfMatrix3d& m2) 405 { 406 return(m1 * m2.GetInverse()); 407 } 408 409 /// Returns the product of a matrix \e m and a column vector \e vec. 410 friend inline GfVec3d operator *(const GfMatrix3d& m, const GfVec3d& vec) { 411 return GfVec3d(vec[0] * m._mtx[0][0] + vec[1] * m._mtx[0][1] + vec[2] * m._mtx[0][2], 412 vec[0] * m._mtx[1][0] + vec[1] * m._mtx[1][1] + vec[2] * m._mtx[1][2], 413 vec[0] * m._mtx[2][0] + vec[1] * m._mtx[2][1] + vec[2] * m._mtx[2][2]); 414 } 415 416 /// Returns the product of row vector \e vec and a matrix \e m. 417 friend inline GfVec3d operator *(const GfVec3d &vec, const GfMatrix3d& m) { 418 return GfVec3d(vec[0] * m._mtx[0][0] + vec[1] * m._mtx[1][0] + vec[2] * m._mtx[2][0], 419 vec[0] * m._mtx[0][1] + vec[1] * m._mtx[1][1] + vec[2] * m._mtx[2][1], 420 vec[0] * m._mtx[0][2] + vec[1] * m._mtx[1][2] + vec[2] * m._mtx[2][2]); 421 } 422 423 /// Returns the product of a matrix \e m and a column vector \e vec. 424 /// Note that the return type is a \c GfVec3f. 425 GF_API 426 friend GfVec3f operator *(const GfMatrix3d& m, const GfVec3f& vec); 427 428 /// Returns the product of row vector \e vec and a matrix \e m. 429 /// Note that the return type is a \c GfVec3f. 430 GF_API 431 friend GfVec3f operator *(const GfVec3f &vec, const GfMatrix3d& m); 432 433 /// Sets matrix to specify a uniform scaling by \e scaleFactor. 434 GF_API 435 GfMatrix3d& SetScale(double scaleFactor); 436 437 /// \name 3D Transformation Utilities 438 /// @{ 439 440 /// Sets the matrix to specify a rotation equivalent to \e rot. 441 GF_API 442 GfMatrix3d& SetRotate(const GfQuatd &rot); 443 444 /// Sets the matrix to specify a rotation equivalent to \e rot. 445 GF_API 446 GfMatrix3d& SetRotate(const GfRotation &rot); 447 448 /// Sets the matrix to specify a nonuniform scaling in x, y, and z by 449 /// the factors in vector \e scaleFactors. 450 GF_API 451 GfMatrix3d& SetScale(const GfVec3d &scaleFactors); 452 453 /// Returns the rotation corresponding to this matrix. This works 454 /// well only if the matrix represents a rotation. 455 /// 456 /// For good results, consider calling Orthonormalize() before calling 457 /// this method. 458 GF_API 459 GfRotation ExtractRotation() const; 460 461 /// Decompose the rotation corresponding to this matrix about 3 462 /// orthogonal axes. If the axes are not orthogonal, warnings 463 /// will be spewed. 464 /// 465 /// This is a convenience method that is equivalent to calling 466 /// ExtractRotation().Decompose(). 467 GF_API 468 GfVec3d DecomposeRotation(const GfVec3d &axis0, 469 const GfVec3d &axis1, 470 const GfVec3d &axis2 ) const; 471 472 /// Returns the quaternion corresponding to this matrix. This works 473 /// well only if the matrix represents a rotation. 474 /// 475 /// For good results, consider calling Orthonormalize() before calling 476 /// this method. 477 GF_API 478 GfQuaternion ExtractRotationQuaternion() const; 479 480 /// @} 481 482 private: 483 /// Set the matrix to the rotation given by a quaternion, 484 /// defined by the real component \p r and imaginary components \p i. 485 void _SetRotateFromQuat(double r, const GfVec3d& i); 486 487 488 private: 489 /// Matrix storage, in row-major order. 490 GfMatrixData<double, 3, 3> _mtx; 491 492 // Friend declarations 493 friend class GfMatrix3f; 494 }; 495 496 497 /// Tests for equality within a given tolerance, returning \c true if the 498 /// difference between each component of the matrix is less than or equal 499 /// to \p tolerance, or false otherwise. 500 GF_API 501 bool GfIsClose(GfMatrix3d const &m1, GfMatrix3d const &m2, double tolerance); 502 503 /// Output a GfMatrix3d 504 /// \ingroup group_gf_DebuggingOutput 505 GF_API std::ostream& operator<<(std::ostream &, GfMatrix3d const &); 506 507 PXR_NAMESPACE_CLOSE_SCOPE 508 509 #endif // PXR_BASE_GF_MATRIX3D_H 510