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 #ifndef PXR_BASE_GF_TRANSFORM_H
25 #define PXR_BASE_GF_TRANSFORM_H
26 
27 /// \file gf/transform.h
28 /// \ingroup group_gf_LinearAlgebra
29 
30 #include "pxr/pxr.h"
31 #include "pxr/base/gf/rotation.h"
32 #include "pxr/base/gf/vec3d.h"
33 #include "pxr/base/gf/api.h"
34 
35 #include <iosfwd>
36 
37 PXR_NAMESPACE_OPEN_SCOPE
38 
39 class GfMatrix4d;
40 
41 /// \class GfTransform
42 /// \ingroup group_gf_LinearAlgebra
43 ///
44 /// Basic type: Compound linear transformation.
45 ///
46 /// This class represents a linear transformation specified as a series of
47 /// individual components: a \em translation, a \em rotation, a \em scale, a
48 /// \em pivotPosition, and a \em pivotOrientation.  When applied to a point,
49 /// the point will be transformed as follows (in order):
50 ///
51 /// \li Scaled by the \em scale with respect to \em pivotPosition and the
52 /// orientation specified by the \em pivotOrientation.
53 /// \li Rotated by the \em rotation about \em pivotPosition.
54 /// \li Translated by \em Translation
55 ///
56 /// That is, the cumulative matrix that this represents looks like this.
57 ///
58 /// \code
59 /// M = -P * -O * S * O * R * P * T
60 /// \endcode
61 ///
62 /// where
63 /// \li \em T is the \em translation matrix
64 /// \li \em P is the matrix that translates by \em pivotPosition
65 /// \li \em R is the \em rotation matrix
66 /// \li \em O is the matrix that rotates to \em pivotOrientation
67 /// \li \em S is the \em scale matrix
68 ///
69 class GfTransform {
70 
71   public:
72 
73     /// The default constructor sets the component values to the
74     /// identity transformation.
GfTransform()75     GfTransform() {
76         SetIdentity();
77     }
78 
79     /// This constructor initializes the transformation from all
80     /// component values.  This is the constructor used by 2x code.
GfTransform(const GfVec3d & scale,const GfRotation & pivotOrientation,const GfRotation & rotation,const GfVec3d & pivotPosition,const GfVec3d & translation)81     GfTransform(const GfVec3d &scale,
82                 const GfRotation &pivotOrientation,
83                 const GfRotation &rotation,
84                 const GfVec3d &pivotPosition,
85                 const GfVec3d &translation) {
86         Set(scale, pivotOrientation, rotation, pivotPosition, translation);
87     }
88 
89     /// This constructor initializes the transformation from all
90     /// component values.  This is the constructor used by 3x code.
GfTransform(const GfVec3d & translation,const GfRotation & rotation,const GfVec3d & scale,const GfVec3d & pivotPosition,const GfRotation & pivotOrientation)91     GfTransform(const GfVec3d &translation,
92                 const GfRotation &rotation,
93                 const GfVec3d &scale,
94                 const GfVec3d &pivotPosition,
95                 const GfRotation &pivotOrientation) {
96         Set(translation, rotation, scale, pivotPosition, pivotOrientation);
97     }
98 
99     /// This constructor initializes the transformation with a matrix.  See
100     /// SetMatrix() for more information.
GfTransform(const GfMatrix4d & m)101     GfTransform(const GfMatrix4d &m) {
102         SetIdentity();
103         SetMatrix(m);
104     }
105 
106     /// Sets the transformation from all component values.
107     /// This constructor orders its arguments the way that 2x expects.
108     GF_API
109     GfTransform &       Set(const GfVec3d &scale,
110                             const GfRotation &pivotOrientation,
111                             const GfRotation &rotation,
112                             const GfVec3d &pivotPosition,
113                             const GfVec3d &translation);
114 
115     /// Sets the transformation from all component values.
116     /// This constructor orders its arguments the way that 3x expects.
Set(const GfVec3d & translation,const GfRotation & rotation,const GfVec3d & scale,const GfVec3d & pivotPosition,const GfRotation & pivotOrientation)117     GfTransform &       Set(const GfVec3d &translation,
118                             const GfRotation &rotation,
119                             const GfVec3d &scale,
120                             const GfVec3d &pivotPosition,
121                             const GfRotation &pivotOrientation) {
122         return Set(scale, pivotOrientation, rotation,
123                    pivotPosition, translation);
124     }
125 
126     /// Sets the transform components to implement the transformation
127     /// represented by matrix \p m , ignoring any projection. This tries to
128     /// leave the current center unchanged.
129     GF_API
130     GfTransform &       SetMatrix(const GfMatrix4d &m);
131 
132     /// Sets the transformation to the identity transformation.
133     GF_API
134     GfTransform &       SetIdentity();
135 
136     /// Sets the scale component, leaving all others untouched.
SetScale(const GfVec3d & scale)137     void                SetScale(const GfVec3d &scale) {
138         _scale = scale;
139     }
140 
141     /// Sets the pivot orientation component, leaving all others untouched.
SetPivotOrientation(const GfRotation & pivotOrient)142     void                SetPivotOrientation(const GfRotation &pivotOrient) {
143         _pivotOrientation = pivotOrient;
144     }
145 
146     /// Sets the pivot orientation component, leaving all others untouched.
SetScaleOrientation(const GfRotation & pivotOrient)147     void                SetScaleOrientation(const GfRotation &pivotOrient) {
148         SetPivotOrientation(pivotOrient);
149     }
150 
151     /// Sets the rotation component, leaving all others untouched.
SetRotation(const GfRotation & rotation)152     void                SetRotation(const GfRotation &rotation) {
153         _rotation = rotation;
154     }
155 
156     /// Sets the pivot position component, leaving all others untouched.
SetPivotPosition(const GfVec3d & pivPos)157     void                SetPivotPosition(const GfVec3d &pivPos) {
158         _pivotPosition = pivPos;
159     }
160 
161     /// Sets the pivot position component, leaving all others untouched.
SetCenter(const GfVec3d & pivPos)162     void                SetCenter(const GfVec3d &pivPos) {
163         SetPivotPosition(pivPos);
164     }
165 
166     /// Sets the translation component, leaving all others untouched.
SetTranslation(const GfVec3d & translation)167     void                SetTranslation(const GfVec3d &translation) {
168         _translation = translation;
169     }
170 
171     /// Returns the scale component.
GetScale()172     const GfVec3d &     GetScale() const {
173         return _scale;
174     }
175 
176     /// Returns the pivot orientation component.
GetPivotOrientation()177     const GfRotation &  GetPivotOrientation() const {
178         return _pivotOrientation;
179     }
180 
181     /// Returns the scale orientation component.
GetScaleOrientation()182     const GfRotation &  GetScaleOrientation() const {
183         return GetPivotOrientation();
184     }
185 
186     /// Returns the rotation component.
GetRotation()187     const GfRotation &  GetRotation() const {
188         return _rotation;
189     }
190 
191     /// Returns the pivot position component.
GetPivotPosition()192     const GfVec3d &     GetPivotPosition() const {
193         return _pivotPosition;
194     }
195 
196     /// Returns the pivot position component.
GetCenter()197     const GfVec3d &     GetCenter() const {
198         return GetPivotPosition();
199     }
200 
201     /// Returns the translation component.
GetTranslation()202     const GfVec3d &     GetTranslation() const {
203         return _translation;
204     }
205 
206     /// Returns a \c GfMatrix4d that implements the cumulative transformation.
207     GF_API
208     GfMatrix4d          GetMatrix() const;
209 
210     /// Component-wise transform equality test. All components must match
211     /// exactly for transforms to be considered equal.
212     GF_API
213     bool                operator ==(const GfTransform &xf) const;
214 
215     /// Component-wise transform inequality test. All components must match
216     /// exactly for transforms to be considered equal.
217     bool                operator !=(const GfTransform &xf) const {
218         return ! (*this == xf);
219     }
220 
221     /// Post-multiplies transform \p xf into this transform.
222     GF_API
223     GfTransform &       operator *=(const GfTransform &xf);
224 
225     /// Returns the product of transforms \p xf1 and \p xf2.
226     friend GfTransform  operator *(const GfTransform &xf1,
227                                    const GfTransform &xf2) {
228         GfTransform xf = xf1;
229         return xf *= xf2;
230     }
231 
232   private:
233     /// translation
234     GfVec3d             _translation;
235     /// rotation
236     GfRotation          _rotation;
237     /// scale factors
238     GfVec3d             _scale;
239     /// orientation used for scaling and rotation
240     GfRotation          _pivotOrientation;
241     /// center of rotation and scaling
242     GfVec3d             _pivotPosition;
243 };
244 
245 /// Output a GfTransform using the format
246 /// [scale, scaleorientation, rotation, center, translation].
247 /// \ingroup group_gf_DebuggingOutput
248 GF_API std::ostream& operator<<(std::ostream&, const GfTransform&);
249 
250 PXR_NAMESPACE_CLOSE_SCOPE
251 
252 #endif // PXR_BASE_GF_TRANSFORM_H
253