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_MATRIX3F_H 29 #define PXR_BASE_GF_MATRIX3F_H 30 31 /// \file gf/matrix3f.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/vec3f.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 GfMatrix3f> { static const bool value = true; }; 50 51 class GfMatrix3d; 52 class GfMatrix3f; 53 class GfRotation; 54 class GfQuaternion; 55 class GfQuatf; 56 57 /// \class GfMatrix3f 58 /// \ingroup group_gf_LinearAlgebra 59 /// 60 /// Stores a 3x3 matrix of \c float 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 GfMatrix3f 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 GfMatrix3f 83 { 84 public: 85 typedef float 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 GfMatrix3f() = default; 92 93 /// Constructor. Initializes the matrix from 9 independent 94 /// \c float values, specified in row-major order. For example, 95 /// parameter \e m10 specifies the value in row 1 and column 0. 96 GfMatrix3f(float m00, float m01, float m02, 97 float m10, float m11, float m12, 98 float m20, float m21, float 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 float values, specified in row-major order. 106 GfMatrix3f(const float m[3][3]) { 107 Set(m); 108 } 109 110 /// Constructor. Explicitly initializes the matrix to \e s times the 111 /// identity matrix. 112 explicit GfMatrix3f(float s) { 113 SetDiagonal(s); 114 } 115 116 /// This explicit constructor initializes the matrix to \p s times 117 /// the identity matrix. 118 explicit GfMatrix3f(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 GfMatrix3f(const GfVec3f& 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 GfMatrix3f(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 GfMatrix3f(const std::vector< std::vector<float> >& v); 145 146 /// Constructor. Initialize matrix from rotation. 147 GF_API 148 GfMatrix3f(const GfRotation& rot); 149 150 /// Constructor. Initialize matrix from a quaternion. 151 GF_API 152 explicit GfMatrix3f(const GfQuatf& rot); 153 154 /// This explicit constructor converts a "double" matrix to a "float" matrix. 155 GF_API 156 explicit GfMatrix3f(const class GfMatrix3d& m); 157 158 /// Sets a row of the matrix from a Vec3. 159 void SetRow(int i, const GfVec3f & 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 GfVec3f & 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 GfVec3f GetRow(int i) const { 174 return GfVec3f(_mtx[i][0], _mtx[i][1], _mtx[i][2]); 175 } 176 177 /// Gets a column of the matrix as a Vec3. 178 GfVec3f GetColumn(int i) const { 179 return GfVec3f(_mtx[0][i], _mtx[1][i], _mtx[2][i]); 180 } 181 182 /// Sets the matrix from 9 independent \c float values, 183 /// specified in row-major order. For example, parameter \e m10 specifies 184 /// the value in row 1 and column 0. 185 GfMatrix3f& Set(float m00, float m01, float m02, 186 float m10, float m11, float m12, 187 float m20, float m21, float 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 float 195 /// values, specified in row-major order. 196 GfMatrix3f& Set(const float 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 GfMatrix3f& SetIdentity() { 211 return SetDiagonal(1); 212 } 213 214 /// Sets the matrix to zero. 215 GfMatrix3f& SetZero() { 216 return SetDiagonal(0); 217 } 218 219 /// Sets the matrix to \e s times the identity matrix. 220 GF_API 221 GfMatrix3f& SetDiagonal(float s); 222 223 /// Sets the matrix to have diagonal (<c>v[0], v[1], v[2]</c>). 224 GF_API 225 GfMatrix3f& SetDiagonal(const GfVec3f&); 226 227 /// Fills a 3x3 array of \c float values with the values in 228 /// the matrix, specified in row-major order. 229 GF_API 230 float* Get(float m[3][3]) const; 231 232 /// Returns raw access to components of matrix as an array of 233 /// \c float values. Components are in row-major order. 234 float* data() { 235 return _mtx.GetData(); 236 } 237 238 /// Returns const raw access to components of matrix as an array of 239 /// \c float values. Components are in row-major order. 240 const float* data() const { 241 return _mtx.GetData(); 242 } 243 244 /// Returns vector components as an array of \c float values. 245 float* GetArray() { 246 return _mtx.GetData(); 247 } 248 249 /// Returns vector components as a const array of \c float values. 250 const float* 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 /// float values so that standard indexing (such as <c>m[0][1]</c>) 256 /// works correctly. 257 float* operator [](int i) { return _mtx[i]; } 258 259 /// Accesses an indexed row \e i of the matrix as an array of 3 \c 260 /// float values so that standard indexing (such as <c>m[0][1]</c>) 261 /// works correctly. 262 const float* operator [](int i) const { return _mtx[i]; } 263 264 /// Hash. 265 friend inline size_t hash_value(GfMatrix3f const &m) { 266 int nElems = 3 * 3; 267 size_t h = 0; 268 const float *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 GfMatrix3f 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 GfMatrix3f 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 GfMatrix3f 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 GfMatrix3f& operator *=(const GfMatrix3f& m); 348 349 /// Multiplies the matrix by a float. 350 GF_API 351 GfMatrix3f& operator *=(double); 352 353 /// Returns the product of a matrix and a float. 354 friend GfMatrix3f operator *(const GfMatrix3f& m1, double d) 355 { 356 GfMatrix3f m = m1; 357 return m *= d; 358 } 359 360 /// 361 // Returns the product of a matrix and a float. 362 friend GfMatrix3f operator *(double d, const GfMatrix3f& m) 363 { 364 return m * d; 365 } 366 367 /// Adds matrix \e m to this matrix. 368 GF_API 369 GfMatrix3f& operator +=(const GfMatrix3f& m); 370 371 /// Subtracts matrix \e m from this matrix. 372 GF_API 373 GfMatrix3f& operator -=(const GfMatrix3f& m); 374 375 /// Returns the unary negation of matrix \e m. 376 GF_API 377 friend GfMatrix3f operator -(const GfMatrix3f& m); 378 379 /// Adds matrix \e m2 to \e m1 380 friend GfMatrix3f operator +(const GfMatrix3f& m1, const GfMatrix3f& m2) 381 { 382 GfMatrix3f tmp(m1); 383 tmp += m2; 384 return tmp; 385 } 386 387 /// Subtracts matrix \e m2 from \e m1. 388 friend GfMatrix3f operator -(const GfMatrix3f& m1, const GfMatrix3f& m2) 389 { 390 GfMatrix3f tmp(m1); 391 tmp -= m2; 392 return tmp; 393 } 394 395 /// Multiplies matrix \e m1 by \e m2. 396 friend GfMatrix3f operator *(const GfMatrix3f& m1, const GfMatrix3f& m2) 397 { 398 GfMatrix3f 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 GfMatrix3f operator /(const GfMatrix3f& m1, const GfMatrix3f& 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 GfVec3f operator *(const GfMatrix3f& m, const GfVec3f& vec) { 411 return GfVec3f(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 GfVec3f operator *(const GfVec3f &vec, const GfMatrix3f& m) { 418 return GfVec3f(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 /// Sets matrix to specify a uniform scaling by \e scaleFactor. 424 GF_API 425 GfMatrix3f& SetScale(float scaleFactor); 426 427 /// \name 3D Transformation Utilities 428 /// @{ 429 430 /// Sets the matrix to specify a rotation equivalent to \e rot. 431 GF_API 432 GfMatrix3f& SetRotate(const GfQuatf &rot); 433 434 /// Sets the matrix to specify a rotation equivalent to \e rot. 435 GF_API 436 GfMatrix3f& SetRotate(const GfRotation &rot); 437 438 /// Sets the matrix to specify a nonuniform scaling in x, y, and z by 439 /// the factors in vector \e scaleFactors. 440 GF_API 441 GfMatrix3f& SetScale(const GfVec3f &scaleFactors); 442 443 /// Returns the rotation corresponding to this matrix. This works 444 /// well only if the matrix represents a rotation. 445 /// 446 /// For good results, consider calling Orthonormalize() before calling 447 /// this method. 448 GF_API 449 GfRotation ExtractRotation() const; 450 451 /// Decompose the rotation corresponding to this matrix about 3 452 /// orthogonal axes. If the axes are not orthogonal, warnings 453 /// will be spewed. 454 /// 455 /// This is a convenience method that is equivalent to calling 456 /// ExtractRotation().Decompose(). 457 GF_API 458 GfVec3f DecomposeRotation(const GfVec3f &axis0, 459 const GfVec3f &axis1, 460 const GfVec3f &axis2 ) const; 461 462 /// Returns the quaternion corresponding to this matrix. This works 463 /// well only if the matrix represents a rotation. 464 /// 465 /// For good results, consider calling Orthonormalize() before calling 466 /// this method. 467 GF_API 468 GfQuaternion ExtractRotationQuaternion() const; 469 470 /// @} 471 472 private: 473 /// Set the matrix to the rotation given by a quaternion, 474 /// defined by the real component \p r and imaginary components \p i. 475 void _SetRotateFromQuat(float r, const GfVec3f& i); 476 477 478 private: 479 /// Matrix storage, in row-major order. 480 GfMatrixData<float, 3, 3> _mtx; 481 482 // Friend declarations 483 friend class GfMatrix3d; 484 }; 485 486 487 /// Tests for equality within a given tolerance, returning \c true if the 488 /// difference between each component of the matrix is less than or equal 489 /// to \p tolerance, or false otherwise. 490 GF_API 491 bool GfIsClose(GfMatrix3f const &m1, GfMatrix3f const &m2, double tolerance); 492 493 /// Output a GfMatrix3f 494 /// \ingroup group_gf_DebuggingOutput 495 GF_API std::ostream& operator<<(std::ostream &, GfMatrix3f const &); 496 497 PXR_NAMESPACE_CLOSE_SCOPE 498 499 #endif // PXR_BASE_GF_MATRIX3F_H 500