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  {
160  // Set m to the transform myStretch*myRotate*myTranslate
161  if (!myStretch.isIdentity())
162  {
163  UT_Matrix3T<T> sr;
164  myRotate.getRotationMatrix(sr);
165  sr.leftMult(myStretch);
166  m = sr;
167  }
168  else
169  myRotate.getTransformMatrix(m);
170 
171  m.setTranslates(myTranslate);
172  }
173 
175  {
177  UT_Vector3T<T> s, r, t;
179  UT_Matrix4T<T> mat = m;
180 
181 
182  bool success = mat.makeRigidMatrix(&stretch);
183  if (success)
184  {
185  mat.explode(xord, r, s, t);
186  stretch.scale(s);
187  setTransform(t.x(), t.y(), t.z(), r.x(), r.y(),
188  r.z(), s.x(), s.y(), s.z());
189  myStretch = stretch.averagedSymMatrix3();
190  }
191  else
192  {
193  if (!m.explode(xord, r, s, t))
194  {
195  setTransform(
196  t.x(), t.y(), t.z(), r.x(), r.y(), r.z(),
197  s.x(), s.y(), s.z());
198  }
199  else
200  {
201  UT_ASSERT_MSG(false, "Failed to crack matrix");
202  identity();
203  }
204  }
205  }
206  // ensures that the dot product of ref and the rotation is non-negative
208  {
209  setMatrix4(m);
210  if (dot(ref, myRotate) <= 0)
211  {
212  myRotate = -myRotate;
213  }
214  }
215 
216 private:
217  UT_SymMatrix3T<T> myStretch;
218  UT_QuaternionT<T> myRotate;
219  UT_Vector3T<T> myTranslate;
220 };
221 
225 
226 // Declare as POD for UT_Array optimizations.
229 
230 #endif
GLint ref
Definition: glcorearb.h:123
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1221
void leftMult(const UT_SymMatrix3T< S > &m)
Multiply given symmetric matrix on the left.
Definition: UT_Matrix3.h:340
UT_SymMatrix3T< T > averagedSymMatrix3() const
Convert this to a symmetric matrix, using averaged components.
Definition: UT_Matrix3.h:225
GU_AgentXformT(T scale)
Definition: GU_AgentXform.h:28
GLenum GLenum GLenum GLenum GLenum scale
Definition: glew.h:14163
void scale(T sx, T sy, T sz)
Definition: UT_Matrix3.h:849
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)
void setLerp(const type &a, const type &b, T t)
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:651
3D Vector class.
GLdouble GLdouble t
Definition: glew.h:1403
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:174
const UT_SymMatrix3T< T > & stretch() const
Definition: GU_AgentXform.h:44
SYS_FORCE_INLINE T & y()
Definition: UT_Vector3.h:508
void getMatrix4(UT_Matrix4T< T > &m) const
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.
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1221
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
SYS_FORCE_INLINE T & z()
Definition: UT_Vector3.h:510
int explode(const UT_XformOrder &order, UT_Vector3F &r, UT_Vector3F &s, UT_Vector3F &t, UT_Vector3F *shears=0) const
Definition: UT_Matrix4.h:932
#define SYS_DECLARE_IS_POD(T)
Declare a type as POD.
void setTranslates(const UT_Vector3T< S > &translates)
Definition: UT_Matrix4.h:1375
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: UT_Quaternion.h:51
const GLdouble * m
Definition: glew.h:9166
SYS_FORCE_INLINE T & x()
Definition: UT_Vector3.h:506
void addScaled(T s, const type &xform)
GLboolean r
Definition: glcorearb.h:1221
GLdouble s
Definition: glew.h:1395
const UT_QuaternionT< T > & rotate() const
Definition: GU_AgentXform.h:45