HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_AgentXform.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  */
6 
7 #ifndef __GU_AgentXform__
8 #define __GU_AgentXform__
9 
10 #include <SYS/SYS_TypeDecorate.h>
11 #include <UT/UT_Matrix4.h>
12 #include <UT/UT_Quaternion.h>
13 #include <UT/UT_SymMatrix3.h>
14 #include <UT/UT_Vector3.h>
15 #include <UT/UT_VectorTypes.h>
16 #include <UT/UT_XformOrder.h>
17 
18 /// A factored transform geared for animation blending.
19 template <typename T>
21 {
22 public:
24 
26  GU_AgentXformT() = default;
27 
29  : myStretch(scale)
30  , myRotate(0, 0, 0, 0)
31  , myTranslate(0, 0, 0)
32  {
33  }
34 
35  /// Convert from another floating point type.
36  template <typename S>
37  explicit GU_AgentXformT(const GU_AgentXformT<S> &other)
38  : myStretch(UT_SymMatrix3T<T>(other.stretch()))
39  , myRotate(UT_QuaternionT<T>(other.rotate()))
40  , myTranslate(UT_Vector3T<T>(other.translate()))
41  {
42  }
43 
44  const UT_SymMatrix3T<T>& stretch() const { return myStretch; }
45  const UT_QuaternionT<T>& rotate() const { return myRotate; }
46  const UT_Vector3T<T>& translate() const { return myTranslate; }
47 
48  void zero()
49  {
50  myStretch.zero();
51  myRotate.assign(0, 0, 0, 0);
52  myTranslate.assign(0, 0, 0);
53  }
54  void identity()
55  {
56  myStretch.identity();
57  myRotate.identity();
58  myTranslate.assign(0, 0, 0);
59  }
60 
61  /// Set the transform, in SRT/XYZ transform order.
62  /// The rotations are given in radians.
64  T tx, T ty, T tz,
65  T rx, T ry, T rz,
66  T sx, T sy, T sz)
67  {
69  myStretch.setScale(sx, sy, sz);
70  myRotate.updateFromEuler(UT_Vector3T<T>(rx, ry, rz), xord);
71  myTranslate.assign(tx, ty, tz);
72  }
73 
74  /// Set the transform, in SRT transform order.
75  /// The rotations are specified by a quaternion.
77  const UT_Vector3T<T> &t, const UT_QuaternionT<T> &r,
78  const UT_Vector3T<T> &s)
79  {
80  myStretch.setScale(s);
81  myRotate = r;
82  myTranslate = t;
83  }
84 
85  template <typename S>
87  S& tx, S& ty, S& tz,
88  S& rx, S& ry, S& rz,
89  S& sx, S& sy, S& sz) const
90  {
91  tx = myTranslate[0];
92  ty = myTranslate[1];
93  tz = myTranslate[2];
94 
96  UT_Vector3D r = myRotate.computeRotations(xord);
97  rx = r[0];
98  ry = r[1];
99  rz = r[2];
100 
101  sx = myStretch(0, 0);
102  sy = myStretch(1, 1);
103  sz = myStretch(2, 2);
104  }
105 
106  /// Set this to a linear interpolation of the two given transforms:
107  /// *this = a + t*(b - a)
108  void setLerp(const type& a, const type& b, T t)
109  {
110  myStretch.lerp(a.myStretch, b.myStretch, t);
111 
112  if (dot(a.myRotate, b.myRotate) >= 0)
113  myRotate.lerp(a.myRotate, b.myRotate, t);
114  else
115  myRotate.lerp(a.myRotate, -b.myRotate, t);
116  // NOTE: We don't normalize myRotate since this is already handled when
117  // we call UT_QuaternionT::getRotationMatrix().
118 
119  myTranslate = SYSlerp(a.myTranslate, b.myTranslate, t);
120  }
121 
122  /// Same as setLerp, but this assumes that a and b's rotation
123  /// matrices are lined up.
124  void setLerpAligned(const type& a, const type& b, T t)
125  {
126  myStretch.lerp(a.myStretch, b.myStretch, t);
127  myRotate.lerp(a.myRotate, b.myRotate, t);
128  myTranslate = SYSlerp(a.myTranslate, b.myTranslate, t);
129  }
130 
131  void addScaled(T s, const type& xform)
132  {
133  myStretch += xform.myStretch * s;
134  if (dot(myRotate, xform.myRotate) >= 0)
135  myRotate += xform.myRotate * s;
136  else
137  myRotate += xform.myRotate * -s;
138  myTranslate += xform.myTranslate * s;
139  }
140 
141  /// Perform an additive blend with the specified percentage.
142  void concat(T t, const type& xform)
143  {
144  myRotate.normalize();
145 
146  myTranslate += myRotate.rotate(xform.myTranslate * t);
147 
148  UT_QuaternionT<T> additive_r = xform.myRotate;
149  additive_r.normalize();
150  UT_QuaternionT<T> new_r = myRotate * additive_r;
151 
152  if (dot(myRotate, new_r) < 0)
153  new_r.negate();
154 
155  myRotate.lerp(myRotate, new_r, t);
156  }
157 
159  void getMatrix4(UT_Matrix4T<T>& m) const
160  {
161  // Set m to the transform myStretch*myRotate*myTranslate
162  if (!myStretch.isIdentity())
163  {
164  UT_Matrix3T<T> sr;
165  myRotate.getRotationMatrix(sr);
166  sr.leftMult(myStretch);
167  m = sr;
168  }
169  else
170  myRotate.getTransformMatrix(m);
171 
172  m.setTranslates(myTranslate);
173  }
174 
175  void setMatrix4(const UT_Matrix4T<T>& m)
176  {
178  UT_Matrix4T<T> mat = m;
179 
180  bool success = mat.makeRigidMatrix(&stretch);
181  if (success)
182  {
183  myStretch = stretch.averagedSymMatrix3();
184  myRotate.updateFromRotationMatrix(UT_Matrix3T<T>(mat));
185  mat.getTranslates(myTranslate);
186  }
187  else
188  {
190  UT_Vector3T<T> s, r, t;
191  if (!m.explode(xord, r, s, t))
192  {
193  setTransform(
194  t.x(), t.y(), t.z(), r.x(), r.y(), r.z(),
195  s.x(), s.y(), s.z());
196  }
197  else
198  {
199  UT_ASSERT_MSG(false, "Failed to crack matrix");
200  identity();
201  }
202  }
203  }
204  // ensures that the dot product of ref and the rotation is non-negative
206  {
207  setMatrix4(m);
208  if (dot(ref, myRotate) <= 0)
209  {
210  myRotate = -myRotate;
211  }
212  }
213 
214 private:
215  UT_SymMatrix3T<T> myStretch;
216  UT_QuaternionT<T> myRotate;
217  UT_Vector3T<T> myTranslate;
218 };
219 
223 
224 // Declare as POD for UT_Array optimizations.
227 
228 #endif
void leftMult(const UT_SymMatrix3T< S > &m)
Multiply given symmetric matrix on the left.
Definition: UT_Matrix3.h:330
UT_SymMatrix3T< T > averagedSymMatrix3() const
Convert this to a symmetric matrix, using averaged components.
Definition: UT_Matrix3.h:215
GU_AgentXformT(T scale)
Definition: GU_AgentXform.h:28
SYS_FORCE_INLINE GU_AgentXformT()=default
Transformation order of scales, rotates, and translates.
Definition: UT_XformOrder.h:23
bool makeRigidMatrix(UT_Matrix3T< T > *stretch=nullptr, bool reverse=true, const int max_iter=64, const T rel_tol=FLT_EPSILON)
constexpr SYS_FORCE_INLINE T & z() noexcept
Definition: UT_Vector3.h:667
void setLerp(const type &a, const type &b, T t)
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
GLdouble s
Definition: glad.h:3009
GU_AgentXformT< T > type
Definition: GU_AgentXform.h:23
void getTransform(S &tx, S &ty, S &tz, S &rx, S &ry, S &rz, S &sx, S &sy, S &sz) const
Definition: GU_AgentXform.h:86
void setMatrix4(const UT_Matrix4T< T > &m)
Generic symmetric 3x3 matrix.
Definition: UT_SymMatrix3.h:27
void setTransform(T tx, T ty, T tz, T rx, T ry, T rz, T sx, T sy, T sz)
Definition: GU_AgentXform.h:63
const UT_Vector3T< T > & translate() const
Definition: GU_AgentXform.h:46
UT_Matrix2T< T > SYSlerp(const UT_Matrix2T< T > &v1, const UT_Matrix2T< T > &v2, S t)
Definition: UT_Matrix2.h:675
3D Vector class.
GU_AgentXformT(const GU_AgentXformT< S > &other)
Convert from another floating point type.
Definition: GU_AgentXform.h:37
void setLerpAligned(const type &a, const type &b, T t)
void setMatrix4(const UT_Matrix4T< T > &m, const UT_QuaternionT< T > &ref)
#define UT_ASSERT_MSG(ZZ,...)
Definition: UT_Assert.h:159
GA_API const UT_StringHolder scale
const UT_SymMatrix3T< T > & stretch() const
Definition: GU_AgentXform.h:44
GLint ref
Definition: glcorearb.h:124
A factored transform geared for animation blending.
Definition: GU_AgentXform.h:20
fpreal64 dot(const CE_VectorT< T > &a, const CE_VectorT< T > &b)
Definition: CE_Vector.h:130
void concat(T t, const type &xform)
Perform an additive blend with the specified percentage.
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
int explode(const UT_XformOrder &order, UT_Vector3F &r, UT_Vector3F &s, UT_Vector3F &t, UT_Vector3F *shears=0) const
Definition: UT_Matrix4.h:958
#define SYS_DECLARE_IS_POD(T)
Declare a type as POD.
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
GLdouble t
Definition: glad.h:2397
void setTranslates(const UT_Vector3T< S > &translates)
Definition: UT_Matrix4.h:1442
void setTransform(const UT_Vector3T< T > &t, const UT_QuaternionT< T > &r, const UT_Vector3T< T > &s)
Definition: GU_AgentXform.h:76
Quaternion class.
Definition: GEO_Detail.h:48
GLboolean r
Definition: glcorearb.h:1222
void addScaled(T s, const type &xform)
constexpr SYS_FORCE_INLINE T & y() noexcept
Definition: UT_Vector3.h:665
SYS_FORCE_INLINE void getMatrix4(UT_Matrix4T< T > &m) const
void getTranslates(UT_Vector3T< S > &translates) const
Definition: UT_Matrix4.h:1432
const UT_QuaternionT< T > & rotate() const
Definition: GU_AgentXform.h:45
constexpr SYS_FORCE_INLINE T & x() noexcept
Definition: UT_Vector3.h:663