HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_LinearSkinDeformer.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  * NAME: GU_LinearSkinDeformer.h (GU Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GU_LINEARSKINDEFORMER_H_INCLUDED__
12 #define __GU_LINEARSKINDEFORMER_H_INCLUDED__
13 
14 #include "GU_API.h"
16 #include <GA/GA_Range.h>
17 #include <UT/UT_Array.h>
18 #include <UT/UT_Assert.h>
19 #include <UT/UT_DualQuaternion.h>
20 #include <UT/UT_Matrix3.h>
21 #include <UT/UT_Matrix4.h>
22 #include <UT/UT_NonCopyable.h>
23 #include <UT/UT_Quaternion.h>
24 #include <UT/UT_UniquePtr.h>
25 #include <UT/UT_VectorTypes.h>
26 #include <SYS/SYS_Inline.h>
27 #include <SYS/SYS_StaticAssert.h>
28 #include <SYS/SYS_TypeDecorate.h>
29 #include <SYS/SYS_Types.h>
30 
31 #include <stddef.h>
32 
33 
34 class UT_TaskList;
35 class GA_Attribute;
36 class GA_ROAttributeRef;
38 class GU_Detail;
40 
42 {
44  GU_CaptureElement(int i, float w) : myI(i), myW(w) { }
45 
46  bool operator>(const GU_CaptureElement& elem) const
47  {
48  return (myW > elem.myW);
49  }
50 
51  int myI;
52  float myW;
53 };
56 
57 
58 template <typename T>
60 {
62 
63  SYS_FORCE_INLINE GU_DualQuatXformT() = default;
64  SYS_FORCE_INLINE GU_DualQuatXformT(const ThisType&) = default;
65  SYS_FORCE_INLINE GU_DualQuatXformT(ThisType&&) = default;
67  ThisType& operator=(const GU_DualQuatXformT<T>&) = default;
69  ThisType& operator=(GU_DualQuatXformT<T>&&) = default;
70 
73  {
75  myDQ.transform(src * myStretch, dst);
76  return dst;
77  }
80  {
82  myDQ.transform(src, dst);
83  dst *= myStretch;
84  return dst;
85  }
88  {
89  UT_ASSERT(false);
90  return src;
91  }
94  {
95  UT_ASSERT(false);
96  return src;
97  }
100  {
102  myDQ.rotate(src, dst);
103  return dst;
104  }
107  {
108  return src * myDQ.getRotation();
109  }
110 
113 };
116 
117 
118 /// Class representing source data for GU_LinearSkinDeformer
120 {
121 public:
123 
124  int64 getMemoryUsage(bool inclusive) const;
125 
126  /// Reset all state
127  void reset();
128 
129  /// Setup the source geometry. Returns the number of transforms requireds
130  /// to deform using the capture weight attribute. If in error, then 0 is
131  /// returned.
132  /// If max_pt_weights > 0, then it will limit the number of weight entries
133  /// to use per point.
134  int init(
135  const GU_Detail& src,
136  const GA_Range& pt_range,
137  int max_pt_weights = 0);
138 
139  /// Clear the list of appended attributes
140  void clearAttribs();
141 
142  /// Append attribute to be deformed. How it is deformed depends on src's
143  /// GA_TypeInfo. initSrc() must have been called first.
144  void appendAttrib(
145  const GA_Attribute& src_attrib);
146 
147  const GU_Detail* srcGdp() const
148  { return myGdp; }
149  void setSrcGdp(const GU_Detail &src)
150  { myGdp = &src; }
151 
152  exint numPoints() const
153  { return myPointStarts.entries() > 0
154  ? myPointStarts.entries()-1 : 0; }
155 
156  /// Return the number of regions found by initSrc()
157  int numRegions() const
158  { return myRegionXforms.entries(); }
159 
160  /// Return the name given the region index. init() must have been
161  /// called first.
162  const char* regionName(int i) const
163  { return myAttribCaptPath.getPath(i); }
164 
165  /// Static utility method to get capture parameters
166  static bool getCaptureParms(
167  const GU_Detail& src,
168  GA_ROAttributeRef& pcapt,
169  GEO_AttributeCapturePath& attr_cap_path,
170  UT_Array<UT_Matrix4F>& xforms,
171  int& max_pt_regions);
172 
173 private:
174  const GU_Detail* myGdp;
175  GEO_AttributeCapturePath myAttribCaptPath;
176  GA_OffsetArray myPointOffsets;
177  UT_ExintArray myPointStarts;
178  GU_CaptureElementArray myCaptureElements;
179 
180  UT_Array<UT_Matrix4F> myRegionXforms;
181 
182  UT_Array<const GA_Attribute*> myPosAttribs;
183  UT_Array<const GA_Attribute*> myVecAttribs;
184  UT_Array<const GA_Attribute*> myNmlAttribs;
185  UT_Array<const GA_Attribute*> myQuatAttribs;
186 
187  friend class GU_LinearSkinDeformer;
188 };
189 
190 
191 /// Performs linear blend skinning of geometry
193 {
194 public:
196 
197  /// Reset all state
198  void reset();
199 
200  enum Method
201  {
205  };
206 
207  /// Setup the destination geometry. Fails if the destination is missing
208  /// attributes that were appended to deform. A reference to the src is
209  /// maintained until reset() is called.
210  bool init(
211  GU_Detail& dst,
212  const GA_Range& pt_range,
214  Method method = DEFORM_LINEAR,
215  bool create_missing_attribs = false,
216  const char *blend_attrib = nullptr);
217 
218  int numRegions() const
219  { return mySrc->myRegionXforms.entries(); }
220 
221  const char* regionName(int i) const
222  { return mySrc->regionName(i); }
223 
224  /// For debugging purposes, call this before making your
225  /// setRegionTransform() calls to avoid asserts about missing transforms.
227  { UT_IF_ASSERT(myNumTransformsSet=0;) }
228 
229  /// Set deforming transform for region_idx, which matches indices found in
230  /// the capture weight attribute. init() must have been called first.
231  void setRegionTransform(
232  int region_idx,
233  const UT_Matrix4F& xform);
234 
235  /// Set deforming transform for region_idx. To apply the capture region's
236  /// transform use setRegionTransform(). init() must have been called first.
237  void setFullRegionTransform(
238  int region_idx,
239  const UT_Matrix4F& xform);
240 
241  /// Append UT_Tasks that will perform the deformation. The tasks will have
242  /// references to this object, so they must be executed before this object
243  /// is destroyed.
244  ///
245  /// The necessary steps in this specific order:
246  /// 1. N = GU_LinearSkinDeformerSource::init() for the point geometry you
247  /// want to deform
248  /// 2. GU_LinearSkinDeformerSource::appendAttrib() for each src attribute
249  /// you want to deform
250  /// 3. GU_LinearSkinDeformer::init() to set up where to put the results
251  /// 4. Call setRegionTransform() N times for each of the cregions
252  /// 5. Call appendDeformTasks()
253  /// 6. When done with the task list, spawn them: tasks.spawnRootAndWait();
254  ///
255  void appendDeformTasks(
256  UT_TaskList& tasks);
257  void appendInverseDeformTasks(
258  UT_TaskList& tasks);
259 
260  /// Do the deform.
261  ///
262  /// The necessary steps in this specific order:
263  /// 1. N = GU_LinearSkinDeformerSource::init() for the point geometry you
264  /// want to deform
265  /// 2. GU_LinearSkinDeformerSource::appendAttrib() for each src attribute
266  /// you want to deform
267  /// 3. GU_LinearSkinDeformer::init() to set up where to put the results
268  /// 4. Call setRegionTransform() N times for each of the cregions
269  /// 5. Call deform()
270  ///
271  void deform();
272  void inverse_deform();
273 
274 public:
277 
278  static const char* SKIN_LINEAR;
279  static const char* SKIN_DUAL_QUATERNION;
281 
282  static bool getGlobalAttribMethod(const GU_Detail *igdp, Method &type);
283  static bool getGlobalAttribBlendAttrib(const GU_Detail *igdp,
284  UT_StringHolder &blend_attrib);
285 
286 private:
287 
288  void clearXforms();
289 
290  void deformInParallel();
291 
292  template <bool ALIGNED, bool INVERT>
293  void appendLinearTasks(
294  UT_TaskList& tasks);
295  template <bool ALIGNED, bool INVERT>
296  void appendDualQuatTasks(
297  UT_TaskList& tasks);
298  template <bool ALIGNED, bool INVERT>
299  void appendBlendedDualQuatTasks(
300  UT_TaskList& tasks);
301 
302 private:
303  Method myMethod;
304 
305  GU_Detail* myDstGdp;
306  GA_Range myDstRange;
307  UT_Array<GA_Attribute*> myDstPosAttribs;
308  UT_Array<GA_Attribute*> myDstVecAttribs;
309  UT_Array<GA_Attribute*> myDstNmlAttribs;
310  UT_Array<GA_Attribute*> myDstQuatAttribs;
311 
313  mySrc;
314 
315  const GA_Attribute* mySrcBlendAttrib;
316 
317  AttribPtrArray mySrcPromotedAttribs;
318 
319  // Linear blending
320  UT_Array<UT_Matrix4F> myPosXforms;
321  UT_Array<UT_QuaternionF> myQuatXforms;
322 
323  // DualQuaternion blending
324  UT_Array<DualQuatXformF> myDualQuatXforms;
325 
326  // This is only used when assertions are enabled
327  exint myNumTransformsSet;
328 };
329 
330 #endif // __GU_LINEARSKINDEFORMER_H_INCLUDED__
Definition of a geometry attribute.
Definition: GA_Attribute.h:190
SYS_FORCE_INLINE UT_Vector3T< T > transform(const UT_Vector3T< T > &src) const
SYS_FORCE_INLINE UT_Vector3T< T > transformTransposed(const UT_Vector3T< T > &src) const
SYS_FORCE_INLINE UT_QuaternionT< T > transformTransposed(const UT_QuaternionT< T > &src) const
Performs linear blend skinning of geometry.
#define UT_IF_ASSERT(ZZ)
Definition: UT_Assert.h:144
3D Vector class.
UT_Matrix3T< T > myStretch
png_uint_32 i
Definition: png.h:2877
GU_CaptureElement(int i, float w)
UT_DualQuaternionT< T > myDQ
A range of elements in an index-map.
Definition: GA_Range.h:42
long long int64
Definition: SYS_Types.h:107
const char * regionName(int i) const
Class representing source data for GU_LinearSkinDeformer.
This class provides a way to manage a reference to an attribute permitting Read-Only access...
int64 exint
Definition: SYS_Types.h:116
double fpreal64
Definition: SYS_Types.h:192
bool operator>(const GU_CaptureElement &elem) const
int method
Definition: png.h:1924
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
#define SYS_DECLARE_IS_POD(T)
Declare a type as POD.
#define GU_API
Definition: GU_API.h:12
const GU_Detail * srcGdp() const
SYS_FORCE_INLINE UT_QuaternionT< T > transform(const UT_QuaternionT< T > &src) const
GLenum GLenum dst
Definition: glcorearb.h:1792
Quaternion class.
Definition: UT_Quaternion.h:51
static const char * SKIN_BLEND_DUAL_QUATERNION_AND_LINEAR
int numRegions() const
Return the number of regions found by initSrc()
const char * regionName(int i) const
UT_Array< UT_UniquePtr< GA_Attribute > > AttribPtrArray
static const char * SKIN_DUAL_QUATERNION
SYS_FORCE_INLINE UT_QuaternionT< T > rotate(const UT_QuaternionT< T > &src) const
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
SYS_FORCE_INLINE UT_Vector3T< T > rotate(const UT_Vector3T< T > &src) const
static const char * SKIN_LINEAR
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:856
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:126
void setSrcGdp(const GU_Detail &src)
GU_DualQuatXformT< float > DualQuatXformF
GLenum src
Definition: glcorearb.h:1792