HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rotation.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_BASE_GF_ROTATION_H
8 #define PXR_BASE_GF_ROTATION_H
9 
10 /// \file gf/rotation.h
11 /// \ingroup group_gf_LinearAlgebra
12 
13 #include "pxr/pxr.h"
14 #include "pxr/base/gf/quaternion.h"
15 #include "pxr/base/gf/quatd.h"
16 #include "pxr/base/gf/matrix4d.h"
17 #include "pxr/base/gf/vec3d.h"
18 #include "pxr/base/gf/vec3f.h"
19 #include "pxr/base/gf/api.h"
20 #include "pxr/base/tf/hash.h"
21 
22 #include <iosfwd>
23 
25 
26 /// \class GfRotation
27 /// \ingroup group_gf_LinearAlgebra
28 ///
29 /// Basic type: 3-space rotation specification.
30 ///
31 /// This class represents a rotation in 3-space. This stores an axis as a
32 /// normalized vector of 3 \c doubles and an angle in degrees (as a double).
33 /// Rotations follow the right-hand rule: a positive rotation about an axis
34 /// vector appears counter-clockwise when looking from the end of the vector
35 /// toward the origin.
36 ///
37 class GfRotation {
38 
39  public:
40 
41  /// The default constructor leaves the rotation undefined.
43  }
44 
45  /// This constructor initializes the rotation to be \p angle
46  /// degrees about \p axis.
47  GfRotation(const GfVec3d &axis, double angle) {
48  SetAxisAngle(axis, angle);
49  }
50 
51  /// This constructor initializes the rotation from a quaternion.
52  GfRotation(const GfQuaternion &quaternion) {
53  SetQuaternion(quaternion);
54  }
55 
56  /// This constructor initializes the rotation from a quaternion. Note that
57  /// this constructor accepts GfQuatf and GfQuath since they implicitly
58  /// convert to GfQuatd.
59  GfRotation(const GfQuatd &quat) { SetQuat(quat); }
60 
61  /// This constructor initializes the rotation to one that brings
62  /// the \p rotateFrom vector to align with \p rotateTo. The passed
63  /// vectors need not be unit length.
64  GF_API
65  GfRotation(const GfVec3d &rotateFrom, const GfVec3d &rotateTo) {
66  SetRotateInto(rotateFrom, rotateTo);
67  }
68 
69  /// Sets the rotation to be \p angle degrees about \p axis.
70  GfRotation & SetAxisAngle(const GfVec3d &axis, double angle) {
71  _axis = axis;
72  _angle = angle;
73  if (!GfIsClose(_axis * _axis, 1.0, 1e-10))
74  _axis.Normalize();
75  return *this;
76  }
77 
78  /// Sets the rotation from a quaternion. Note that this method accepts
79  /// GfQuatf and GfQuath since they implicitly convert to GfQuatd.
80  GF_API
81  GfRotation & SetQuat(const GfQuatd &quat);
82 
83  /// Sets the rotation from a quaternion.
85  return SetQuat(GfQuatd(quat.GetReal(), quat.GetImaginary()));
86  }
87 
88  /// Sets the rotation to one that brings the \p rotateFrom vector
89  /// to align with \p rotateTo. The passed vectors need not be unit
90  /// length.
91  GF_API
92  GfRotation & SetRotateInto(const GfVec3d &rotateFrom,
93  const GfVec3d &rotateTo);
94 
95  /// Sets the rotation to an identity rotation.
96  /// (This is chosen to be 0 degrees around the positive X axis.)
98  _axis.Set(1.0, 0.0, 0.0);
99  _angle = 0.0;
100  return *this;
101  }
102 
103  /// Returns the axis of rotation.
104  const GfVec3d & GetAxis() const {
105  return _axis;
106  }
107 
108  /// Returns the rotation angle in degrees.
109  double GetAngle() const {
110  return _angle;
111  }
112 
113  /// Returns the rotation expressed as a quaternion.
115  auto quat = GetQuat();
116  return GfQuaternion(quat.GetReal(), quat.GetImaginary());
117  }
118 
119  /// Returns the rotation expressed as a quaternion.
120  GF_API
121  GfQuatd GetQuat() const;
122 
123  /// Returns the inverse of this rotation.
125  return GfRotation(_axis, -_angle);
126  }
127 
128  /// Decompose rotation about 3 orthogonal axes.
129  /// If the axes are not orthogonal, warnings will be spewed.
130  GF_API
131  GfVec3d Decompose( const GfVec3d &axis0,
132  const GfVec3d &axis1,
133  const GfVec3d &axis2 ) const;
134 
135  // Full-featured method to Decompose a rotation matrix into Cardarian
136  // angles.
137  // Axes have must be normalized. If useHint is specified
138  // then the current values stored within thetaTw, thetaFB, thetaLR,
139  // and thetaSw will be treated as hint and used to help choose
140  // an equivalent rotation that is as close as possible to the hints.
141  //
142  // One can use this routine to generate any combination of the three
143  // angles by passing in nullptr for the angle that is to be omitted.
144  //
145  // Passing in valid pointers for all four angles will decompose into
146  // Tw, FB, and LR but allows Sw to be used for best matching of hint
147  // values. It also allows an swShift value to be passed in as a
148  // Sw that is applied after the rotation matrix to get a best fit rotation
149  // in four angles.
150  //
151  // Angles are in radians.
152  //
153  // Specify \p handedness as -1.0 or 1.0, same as for MultiRotate.
154  //
155  // NOTE:
156  // Geppetto math function Originally brought over to extMover
157  // from //depot/main/tools/src/menv/lib/gpt/util.h [10/16/06]
158  // And moved into GfRotation[12/1/08]. Updated for any
159  // combination of three angles [12/1/11].
160  //
161  GF_API
162  static void DecomposeRotation(const GfMatrix4d &rot,
163  const GfVec3d &TwAxis,
164  const GfVec3d &FBAxis,
165  const GfVec3d &LRAxis,
166  double handedness,
167  double *thetaTw,
168  double *thetaFB,
169  double *thetaLR,
170  double *thetaSw = nullptr,
171  bool useHint=false,
172  const double *swShift=nullptr);
173 
174  // This function projects the vectors \p v1 and \p v2 onto the plane
175  // normal to \p axis, and then returns the rotation about \p axis that
176  // brings \p v1 onto \p v2.
177  GF_API
179  const GfVec3d &v2,
180  const GfVec3d &axis);
181 
182  /// Replace the hint angles with the closest rotation of the given
183  /// rotation to the hint.
184  ///
185  /// Each angle in the rotation will be within Pi of the corresponding
186  /// hint angle and the sum of the differences with the hint will
187  /// be minimized. If a given rotation value is null then that angle will
188  /// be treated as 0.0 and ignored in the calculations.
189  ///
190  /// All angles are in radians. The rotation order is Tw/FB/LR/Sw.
191  GF_API
192  static void MatchClosestEulerRotation(
193  double targetTw, double targetFB, double targetLR, double targetSw,
194  double *thetaTw, double *thetaFB, double *thetaLR, double *thetaSw);
195 
196  /// Transforms row vector \p vec by the rotation, returning the result.
197  GF_API
198  GfVec3d TransformDir( const GfVec3d &vec ) const;
199 
200  /// Hash.
201  friend inline size_t hash_value(const GfRotation &r) {
202  return TfHash::Combine(r._axis, r._angle);
203  }
204 
205  /// Component-wise rotation equality test. The axes and angles must match
206  /// exactly for rotations to be considered equal. (To compare equality of
207  /// the actual rotations, you can convert both to quaternions and test the
208  /// results for equality.)
209  bool operator ==(const GfRotation &r) const {
210  return (_axis == r._axis &&
211  _angle == r._angle);
212  }
213 
214  /// Component-wise rotation inequality test. The axes and angles must
215  /// match exactly for rotations to be considered equal. (To compare
216  /// equality of the actual rotations, you can convert both to quaternions
217  /// and test the results for equality.)
218  bool operator !=(const GfRotation &r) const {
219  return ! (*this == r);
220  }
221 
222  /// Post-multiplies rotation \p r into this rotation.
223  GF_API
225 
226  /// Scales rotation angle by multiplying by \p scale.
228  _angle *= scale;
229  return *this;
230  }
231 
232  /// Scales rotation angle by dividing by \p scale.
234  _angle /= scale;
235  return *this;
236  }
237 
238  /// Returns composite rotation of rotations \p r1 and \p r2.
239  friend GfRotation operator *(const GfRotation &r1,
240  const GfRotation &r2) {
241  GfRotation r = r1;
242  return r *= r2;
243  }
244 
245  /// Returns a rotation equivalent to \p r with its angle multiplied
246  /// by \p scale.
247  friend GfRotation operator *(const GfRotation &r, double scale) {
248  GfRotation rTmp = r;
249  return rTmp *= scale;
250  }
251 
252  /// Returns a rotation equivalent to \p r with its angle multiplied
253  /// by \p scale.
254  friend GfRotation operator *(double scale, const GfRotation &r) {
255  return (r * scale);
256  }
257 
258  /// Returns a rotation equivalent to \p r with its angle divided
259  /// by \p scale.
260  friend GfRotation operator /(const GfRotation &r, double scale) {
261  GfRotation rTmp = r;
262  return rTmp /= scale;
263  }
264 
265  private:
266  /// Axis storage.
267  /// This axis is normalized to unit length whenever it is set.
268  GfVec3d _axis;
269  /// Angle storage (represented in degrees).
270  double _angle;
271 };
272 
273 /// Output a GfRotation using the format [(x y z) a].
274 /// \ingroup group_gf_DebuggingOutput
275 GF_API std::ostream& operator<<(std::ostream&, const GfRotation&);
276 
278 
279 #endif // PXR_BASE_GF_ROTATION_H
GfRotation & SetAxisAngle(const GfVec3d &axis, double angle)
Sets the rotation to be angle degrees about axis.
Definition: rotation.h:70
GfRotation GetInverse() const
Returns the inverse of this rotation.
Definition: rotation.h:124
bool operator!=(const GfRotation &r) const
Definition: rotation.h:218
SIM_API const UT_StringHolder angle
GF_API GfQuatd GetQuat() const
Returns the rotation expressed as a quaternion.
GfRotation(const GfQuatd &quat)
Definition: rotation.h:59
GfRotation(const GfQuaternion &quaternion)
This constructor initializes the rotation from a quaternion.
Definition: rotation.h:52
friend size_t hash_value(const GfRotation &r)
Hash.
Definition: rotation.h:201
GA_API const UT_StringHolder rot
double GetReal() const
Returns the real part of the quaternion.
Definition: quaternion.h:67
GF_API GfRotation(const GfVec3d &rotateFrom, const GfVec3d &rotateTo)
Definition: rotation.h:65
GF_API GfVec3d TransformDir(const GfVec3d &vec) const
Transforms row vector vec by the rotation, returning the result.
GF_API GfRotation & SetQuat(const GfQuatd &quat)
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:818
friend GfRotation operator*(const GfRotation &r1, const GfRotation &r2)
Returns composite rotation of rotations r1 and r2.
Definition: rotation.h:239
GA_API const UT_StringHolder scale
GfRotation()
The default constructor leaves the rotation undefined.
Definition: rotation.h:42
GF_API GfRotation & SetRotateInto(const GfVec3d &rotateFrom, const GfVec3d &rotateTo)
GfRotation & SetQuaternion(const GfQuaternion &quat)
Sets the rotation from a quaternion.
Definition: rotation.h:84
GF_API std::ostream & operator<<(std::ostream &, const GfRotation &)
GfRotation & SetIdentity()
Definition: rotation.h:97
GfRotation & operator/=(double scale)
Scales rotation angle by dividing by scale.
Definition: rotation.h:233
GfQuaternion GetQuaternion() const
Returns the rotation expressed as a quaternion.
Definition: rotation.h:114
static GF_API void DecomposeRotation(const GfMatrix4d &rot, const GfVec3d &TwAxis, const GfVec3d &FBAxis, const GfVec3d &LRAxis, double handedness, double *thetaTw, double *thetaFB, double *thetaLR, double *thetaSw=nullptr, bool useHint=false, const double *swShift=nullptr)
GF_API GfRotation & operator*=(const GfRotation &r)
Post-multiplies rotation r into this rotation.
GfRotation(const GfVec3d &axis, double angle)
Definition: rotation.h:47
friend GfRotation operator/(const GfRotation &r, double scale)
Definition: rotation.h:260
static size_t Combine(Args &&...args)
Produce a hash code by combining the hash codes of several objects.
Definition: hash.h:487
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
GfVec3d & Set(double s0, double s1, double s2)
Set all elements with passed arguments.
Definition: vec3d.h:112
bool operator==(const GfRotation &r) const
Definition: rotation.h:209
bool GfIsClose(GfColor const &c1, GfColor const &c2, double tolerance)
Definition: color.h:114
Definition: vec3d.h:45
const GfVec3d & GetAxis() const
Returns the axis of rotation.
Definition: rotation.h:104
GLfloat GLfloat v1
Definition: glcorearb.h:817
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
GF_API GfVec3d Decompose(const GfVec3d &axis0, const GfVec3d &axis1, const GfVec3d &axis2) const
static GF_API void MatchClosestEulerRotation(double targetTw, double targetFB, double targetLR, double targetSw, double *thetaTw, double *thetaFB, double *thetaLR, double *thetaSw)
GLboolean r
Definition: glcorearb.h:1222
Definition: quatd.h:42
static GF_API GfRotation RotateOntoProjected(const GfVec3d &v1, const GfVec3d &v2, const GfVec3d &axis)
const GfVec3d & GetImaginary() const
Returns the imaginary part of the quaternion.
Definition: quaternion.h:72
#define GF_API
Definition: api.h:23
double GetAngle() const
Returns the rotation angle in degrees.
Definition: rotation.h:109