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 // matrix4.template.h file to make changes. 27 28 {% extends "matrix.template.h" %} 29 30 {% block includes %} 31 #include "pxr/base/gf/homogeneous.h" 32 #include "pxr/base/gf/limits.h" 33 #include "pxr/base/gf/math.h" 34 #include "pxr/base/gf/vec3{{ SCL[0] }}.h" 35 {% endblock %} 36 37 {% block forwardDeclarations %} 38 class GfQuat{{ SCL[0] }}; 39 class GfRotation; 40 class GfMatrix3{{ SCL[0] }}; 41 {% endblock %} 42 43 {% block classDocs %} 44 /// <h3>3D Transformations</h3> 45 /// 46 /// The following methods interpret a {{ MAT }} as a 3D 47 /// transformation: SetRotate(), SetScale(), SetTranslate(), SetLookAt(), 48 /// Factor(), ExtractTranslation(), ExtractRotation(), Transform(), TransformDir(). 49 /// By convention, vectors are treated primarily as row vectors, 50 /// implying the following: 51 /// \li Transformation matrices are organized to deal with row 52 /// vectors, not column vectors. For example, the last row of a matrix 53 /// contains the translation amounts. 54 /// \li Each of the Set() methods below completely rewrites the 55 /// matrix; for example, SetTranslate() yields a matrix 56 /// which does nothing but translate. 57 /// \li When multiplying two transformation matrices, the matrix 58 /// on the left applies a more local transformation to a row 59 /// vector. For example, if R represents a rotation 60 /// matrix and T represents a translation matrix, the 61 /// product R*T will rotate a row vector, then translate 62 /// it. 63 {% endblock classDocs %} 64 65 {% block customConstructors %} 66 {% for S in SCALARS %} 67 /// Constructor. Initialize the matrix from {{ DIM }} row vectors of 68 /// {{ S }}. Each vector is expected to length {{ DIM }}. If it is too 69 /// big, only the first {{ DIM }} items will be used. If it is too small, 70 /// uninitialized elements will be filled in with the 71 /// corresponding elements from an identity matrix. 72 /// 73 GF_API 74 explicit {{ MAT }}(const std::vector<{{ S }}>& r0, 75 const std::vector<{{ S }}>& r1, 76 const std::vector<{{ S }}>& r2, 77 const std::vector<{{ S }}>& r3); 78 79 {% endfor %} 80 /// Constructor. Initializes a transformation matrix to perform the 81 /// indicated rotation and translation. 82 GF_API 83 {{ MAT }}(const GfRotation& rotate, 84 const GfVec3{{ SCL[0] }}& translate); 85 86 /// Constructor. Initializes a transformation matrix to perform the 87 /// indicated rotation and translation. 88 GF_API 89 {{ MAT }}(const GfMatrix3{{ SCL[0] }}& rotmx, 90 const GfVec3{{ SCL[0] }}& translate); 91 {% endblock customConstructors %} 92 93 {% block customFunctions %} 94 /// Sets a row of the matrix from a Vec3. 95 /// The fourth element of the row is ignored. 96 void SetRow3(int i, const GfVec3{{ SCL[0] }} & v) { 97 _mtx[i][0] = v[0]; 98 _mtx[i][1] = v[1]; 99 _mtx[i][2] = v[2]; 100 } 101 102 /// Gets a row of the matrix as a Vec3. 103 GfVec3{{ SCL[0] }} GetRow3(int i) const { 104 return GfVec3{{ SCL[0] }}(_mtx[i][0], _mtx[i][1], _mtx[i][2]); 105 } 106 107 /// Returns the determinant of the upper 3x3 matrix. This method is useful 108 /// when the matrix describes a linear transformation such as a rotation or 109 /// scale because the other values in the 4x4 matrix are not important. 110 double GetDeterminant3() const { 111 return _GetDeterminant3(0, 1, 2, 0, 1, 2); 112 } 113 114 /// Returns true, if the row vectors of the upper 3x3 matrix form an 115 /// orthogonal basis. Note they do not have to be unit length for this 116 /// test to return true. 117 bool HasOrthogonalRows3() const { 118 // XXX Should add GfAreOrthogonal(v0, v1, v2) (which also 119 // GfRotation::Decompose() could use). 120 GfVec3{{ SCL[0] }} axis0(GetRow3(0)), axis1(GetRow3(1)), axis2(GetRow3(2)); 121 return (GfAbs(GfDot(axis0, axis1)) < GF_MIN_ORTHO_TOLERANCE && 122 GfAbs(GfDot(axis0, axis2)) < GF_MIN_ORTHO_TOLERANCE && 123 GfAbs(GfDot(axis1, axis2)) < GF_MIN_ORTHO_TOLERANCE); 124 } 125 126 /// Makes the matrix orthonormal in place. This is an iterative method 127 /// that is much more stable than the previous cross/cross method. If the 128 /// iterative method does not converge, a warning is issued. 129 /// 130 /// Returns true if the iteration converged, false otherwise. Leaves any 131 /// translation part of the matrix unchanged. If \a issueWarning is true, 132 /// this method will issue a warning if the iteration does not converge, 133 /// otherwise it will be silent. 134 GF_API 135 bool Orthonormalize(bool issueWarning=true); 136 137 /// Returns an orthonormalized copy of the matrix. 138 GF_API 139 {{ MAT }} GetOrthonormalized(bool issueWarning=true) const; 140 141 /// Returns the sign of the determinant of the upper 3x3 matrix, i.e. 1 142 /// for a right-handed matrix, -1 for a left-handed matrix, and 0 for a 143 /// singular matrix. 144 GF_API 145 double GetHandedness() const; 146 147 /// Returns true if the vectors in the upper 3x3 matrix form a 148 /// right-handed coordinate system. 149 bool IsRightHanded() const { 150 return GetHandedness() == 1.0; 151 } 152 153 /// Returns true if the vectors in the upper 3x3 matrix form a left-handed 154 /// coordinate system. 155 bool IsLeftHanded() const { 156 return GetHandedness() == -1.0; 157 } 158 {% endblock customFunctions %} 159 160 {% block customXformFunctions %} 161 /// Sets matrix to specify a uniform scaling by \e scaleFactor. 162 GF_API 163 {{ MAT }}& SetScale({{ SCL }} scaleFactor); 164 165 /// Returns the matrix with any scaling or shearing removed, 166 /// leaving only the rotation and translation. 167 /// If the matrix cannot be decomposed, returns the original matrix. 168 GF_API 169 {{ MAT }} RemoveScaleShear() const; 170 171 /// \name 3D Transformation Utilities 172 /// @{ 173 174 /// Sets the matrix to specify a rotation equivalent to \e rot, 175 /// and clears the translation. 176 GF_API 177 {{ MAT }}& SetRotate(const GfQuat{{ SCL[0] }} &rot); 178 179 /// Sets the matrix to specify a rotation equivalent to \e rot, 180 /// without clearing the translation. 181 GF_API 182 {{ MAT }}& SetRotateOnly(const GfQuat{{ SCL[0] }} &rot); 183 184 /// Sets the matrix to specify a rotation equivalent to \e rot, 185 /// and clears the translation. 186 GF_API 187 {{ MAT }}& SetRotate(const GfRotation &rot); 188 189 /// Sets the matrix to specify a rotation equivalent to \e rot, 190 /// without clearing the translation. 191 GF_API 192 {{ MAT }}& SetRotateOnly(const GfRotation &rot); 193 194 /// Sets the matrix to specify a rotation equivalent to \e mx, 195 /// and clears the translation. 196 GF_API 197 {{ MAT }}& SetRotate(const GfMatrix3{{ SCL[0] }} &mx); 198 199 /// Sets the matrix to specify a rotation equivalent to \e mx, 200 /// without clearing the translation. 201 GF_API 202 {{ MAT }}& SetRotateOnly(const GfMatrix3{{ SCL[0] }} &mx); 203 204 /// Sets the matrix to specify a nonuniform scaling in x, y, and z by 205 /// the factors in vector \e scaleFactors. 206 GF_API 207 {{ MAT }}& SetScale(const GfVec3{{ SCL[0] }} &scaleFactors); 208 209 /// Sets matrix to specify a translation by the vector \e trans, 210 /// and clears the rotation. 211 GF_API 212 {{ MAT }}& SetTranslate(const GfVec3{{ SCL[0] }} &trans); 213 214 /// Sets matrix to specify a translation by the vector \e trans, 215 /// without clearing the rotation. 216 GF_API 217 {{ MAT }}& SetTranslateOnly(const GfVec3{{ SCL[0] }} &t); 218 219 /// Sets matrix to specify a rotation by \e rotate and a 220 /// translation by \e translate. 221 GF_API 222 {{ MAT }}& SetTransform(const GfRotation& rotate, 223 const GfVec3{{ SCL[0] }}& translate); 224 225 /// Sets matrix to specify a rotation by \e rotmx and a 226 /// translation by \e translate. 227 GF_API 228 {{ MAT }}& SetTransform(const GfMatrix3{{ SCL[0] }}& rotmx, 229 const GfVec3{{ SCL[0] }}& translate); 230 231 /// Sets the matrix to specify a viewing matrix from parameters 232 /// similar to those used by <c>gluLookAt(3G)</c>. \e eyePoint 233 /// represents the eye point in world space. \e centerPoint 234 /// represents the world-space center of attention. \e upDirection 235 /// is a vector indicating which way is up. 236 GF_API 237 {{ MAT }}& SetLookAt(const GfVec3{{ SCL[0] }} &eyePoint, 238 const GfVec3{{ SCL[0] }} ¢erPoint, 239 const GfVec3{{ SCL[0] }} &upDirection); 240 241 /// Sets the matrix to specify a viewing matrix from a world-space 242 /// \e eyePoint and a world-space rotation that rigidly rotates the 243 /// orientation from its canonical frame, which is defined to be 244 /// looking along the <c>-z</c> axis with the <c>+y</c> axis as the up 245 /// direction. 246 GF_API 247 {{ MAT }}& SetLookAt(const GfVec3{{ SCL[0] }} &eyePoint, 248 const GfRotation &orientation); 249 250 /// Factors the matrix into 5 components: 251 /// \li <c>\e M = r * s * -r * u * t</c> 252 /// where 253 /// \li \e t is a translation. 254 /// \li \e u and \e r are rotations, and \e -r is the transpose 255 /// (inverse) of \e r. The \e u matrix may contain shear 256 /// information. 257 /// \li \e s is a scale. 258 /// Any projection information could be returned in matrix \e p, 259 /// but currently p is never modified. 260 /// 261 /// Returns \c false if the matrix is singular (as determined by \e eps). 262 /// In that case, any zero scales in \e s are clamped to \e eps 263 /// to allow computation of \e u. 264 GF_API 265 bool Factor({{ MAT }}* r, GfVec3{{ SCL[0] }}* s, {{ MAT }}* u, 266 GfVec3{{ SCL[0] }}* t, {{ MAT }}* p, 267 {% if SCL == 'double' %} 268 {{ SCL }} eps = 1e-10) const; 269 {% else %} 270 {{ SCL }} eps = 1e-5) const; 271 {% endif %} 272 273 /// Returns the translation part of the matrix, defined as the first three 274 /// elements of the last row. 275 GfVec3{{ SCL[0] }} ExtractTranslation() const { 276 return GfVec3{{ SCL[0] }}(_mtx[3][0], _mtx[3][1], _mtx[3][2]); 277 } 278 279 /// Returns the rotation corresponding to this matrix. This works well 280 /// only if the matrix represents a rotation. 281 /// 282 /// For good results, consider calling Orthonormalize() before calling 283 /// this method. 284 GF_API 285 GfRotation ExtractRotation() const; 286 287 /// Return the rotation corresponding to this matrix as a quaternion. 288 /// This works well only if the matrix represents a rotation. 289 /// 290 /// For good results, consider calling Orthonormalize() before calling 291 /// this method. 292 GF_API 293 GfQuat{{ SCL[0] }} ExtractRotationQuat() const; 294 295 /// Decompose the rotation corresponding to this matrix about 3 orthogonal 296 /// axes. If the axes are not orthogonal, warnings will be spewed. 297 /// 298 /// This is a convenience method that is equivalent to calling 299 /// ExtractRotation().Decompose(). 300 GF_API 301 GfVec3{{ SCL[0] }} DecomposeRotation(const GfVec3{{ SCL[0] }} &axis0, 302 const GfVec3{{ SCL[0] }} &axis1, 303 const GfVec3{{ SCL[0] }} &axis2) const; 304 305 /// Returns the rotation corresponding to this matrix. This works well 306 /// only if the matrix represents a rotation. 307 /// 308 /// For good results, consider calling Orthonormalize() before calling 309 /// this method. 310 GF_API 311 GfMatrix3{{ SCL[0] }} ExtractRotationMatrix() const; 312 313 /// Transforms the row vector \e vec by the matrix, returning the result. 314 /// This treats the vector as a 4-component vector whose fourth component 315 /// is 1. 316 GfVec3d Transform(const GfVec3d &vec) const { 317 return GfProject(GfVec4d( 318 {{ LIST("vec[%(i)s] * _mtx[%(i)s][0]", sep=" + ", num=3) }} + _mtx[3][0], 319 {{ LIST("vec[%(i)s] * _mtx[%(i)s][1]", sep=" + ", num=3) }} + _mtx[3][1], 320 {{ LIST("vec[%(i)s] * _mtx[%(i)s][2]", sep=" + ", num=3) }} + _mtx[3][2], 321 {{ LIST("vec[%(i)s] * _mtx[%(i)s][3]", sep=" + ", num=3) }} + _mtx[3][3])); 322 } 323 324 /// Transforms the row vector \e vec by the matrix, returning the result. 325 /// This treats the vector as a 4-component vector whose fourth component 326 /// is 1. This is an overloaded method; it differs from the other version 327 /// in that it returns a different value type. 328 GfVec3f Transform(const GfVec3f &vec) const { 329 {% if SCL == 'float' %} 330 return (GfProject(GfVec4f( 331 {% else %} 332 return GfVec3f(GfProject(GfVec4d( 333 {% endif %} 334 {{ LIST("vec[%(i)s] * _mtx[%(i)s][0]", sep=" + ", num=3) }} + _mtx[3][0], 335 {{ LIST("vec[%(i)s] * _mtx[%(i)s][1]", sep=" + ", num=3) }} + _mtx[3][1], 336 {{ LIST("vec[%(i)s] * _mtx[%(i)s][2]", sep=" + ", num=3) }} + _mtx[3][2], 337 {{ LIST("vec[%(i)s] * _mtx[%(i)s][3]", sep=" + ", num=3) }} + _mtx[3][3]))); 338 } 339 340 /// Transforms row vector \e vec by the matrix, returning the result. This 341 /// treats the vector as a direction vector, so the translation 342 /// information in the matrix is ignored. That is, it treats the vector as 343 /// a 4-component vector whose fourth component is 0. 344 GfVec3d TransformDir(const GfVec3d &vec) const { 345 return GfVec3d( 346 {{ LIST("vec[%(i)s] * _mtx[%(i)s][0]", sep=" + ", num=3) }}, 347 {{ LIST("vec[%(i)s] * _mtx[%(i)s][1]", sep=" + ", num=3) }}, 348 {{ LIST("vec[%(i)s] * _mtx[%(i)s][2]", sep=" + ", num=3) }}); 349 } 350 351 /// Transforms row vector \e vec by the matrix, returning the result. This 352 /// treats the vector as a direction vector, so the translation 353 /// information in the matrix is ignored. That is, it treats the vector as 354 /// a 4-component vector whose fourth component is 0. This is an 355 /// overloaded method; it differs from the other version in that it 356 /// returns a different value type. 357 GfVec3f TransformDir(const GfVec3f &vec) const { 358 return GfVec3f( 359 {{ LIST("vec[%(i)s] * _mtx[%(i)s][0]", sep=" + ", num=3) }}, 360 {{ LIST("vec[%(i)s] * _mtx[%(i)s][1]", sep=" + ", num=3) }}, 361 {{ LIST("vec[%(i)s] * _mtx[%(i)s][2]", sep=" + ", num=3) }}); 362 } 363 364 /// Transforms the row vector \e vec by the matrix, returning the result. 365 /// This treats the vector as a 4-component vector whose fourth component 366 /// is 1 and ignores the fourth column of the matrix (i.e. assumes it is 367 /// (0, 0, 0, 1)). 368 GfVec3d TransformAffine(const GfVec3d &vec) const { 369 return GfVec3d( 370 {{ LIST("vec[%(i)s] * _mtx[%(i)s][0]", sep=" + ", num=3) }} + _mtx[3][0], 371 {{ LIST("vec[%(i)s] * _mtx[%(i)s][1]", sep=" + ", num=3) }} + _mtx[3][1], 372 {{ LIST("vec[%(i)s] * _mtx[%(i)s][2]", sep=" + ", num=3) }} + _mtx[3][2]); 373 } 374 375 /// Transforms the row vector \e vec by the matrix, returning the result. 376 /// This treats the vector as a 4-component vector whose fourth component 377 /// is 1 and ignores the fourth column of the matrix (i.e. assumes it is 378 /// (0, 0, 0, 1)). 379 GfVec3f TransformAffine(const GfVec3f &vec) const { 380 return GfVec3f( 381 {{ LIST("vec[%(i)s] * _mtx[%(i)s][0]", sep=" + ", num=3) }} + _mtx[3][0], 382 {{ LIST("vec[%(i)s] * _mtx[%(i)s][1]", sep=" + ", num=3) }} + _mtx[3][1], 383 {{ LIST("vec[%(i)s] * _mtx[%(i)s][2]", sep=" + ", num=3) }} + _mtx[3][2]); 384 } 385 /// @} 386 387 private: 388 /// Returns the determinant of the 3x3 submatrix specified by the three 389 /// given row and column indices (0-3 for each). 390 GF_API 391 double _GetDeterminant3(size_t row1, size_t row2, size_t row3, 392 size_t col1, size_t col2, size_t col3) const; 393 394 /// Diagonalizes the upper 3x3 matrix of a matrix known to be symmetric. 395 void _Jacobi3(GfVec3d *eigenvalues, GfVec3d eigenvectors[3]) const; 396 397 /// Set the 3x3 submatrix to the rotation given by a quaternion, 398 /// defined by the real component \p r and imaginary components \p i. 399 void _SetRotateFromQuat({{ SCL }} r, const GfVec3{{ SCL[0] }}& i); 400 401 {% endblock customXformFunctions %} 402