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] }} &centerPoint,
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