HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_MotionClip.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_MotionClip.h ( GU Library, C++)
7  *
8  * COMMENTS: Classes to hold & manipulate motion clips.
9  *
10  * GU_MotionClipRO & GU_MotionClipRW - Containers for motion clips
11  * GU_MotionClipBuilder - Batch modifier for motion clips
12  *
13  */
14 
15 #ifndef __GU_MOTIONCLIP_H_INCLUDED__
16 #define __GU_MOTIONCLIP_H_INCLUDED__
17 
18 #include "GU_API.h"
19 
20 #include "GU_AgentClip.h"
21 #include "GU_MotionClipUtil.h"
22 #include "GU_Hierarchy.h"
23 
24 #include <GA/GA_Types.h>
25 #include <GA/GA_AttributeFilter.h>
26 
27 #include <GOP/GOP_Manager.h>
28 
29 #include <UT/UT_Array.h>
30 #include <UT/UT_Lock.h>
31 #include <UT/UT_StringHolder.h>
32 #include <UT/UT_StringMap.h>
33 #include <UT/UT_TransformUtil.h>
34 
35 #include <SYS/SYS_Inline.h>
36 #include <SYS/SYS_Types.h>
37 
38 #include <utility>
39 
40 /// Read-only animation clip represented in geometry as packed primitives.
41 ///
42 /// The first packed geometry primitive contains the skeleton "topology"
43 /// evaluated at the given rest frame and the remaining packed geometry
44 /// primitives each represent a cached pose (ie. a KineFX skeleton), each
45 /// containing a list of points with joint names and transforms.
46 /// For each pose, the @c time primitive attribute represents where it should
47 /// be in seconds.
48 ///
49 /// Note that the joints in the pose packed primitives must exist in the
50 /// topology packed primitive, but the converse is not necessarily true. The
51 /// pose packed primitive may be missing particular joints from the topology
52 /// packed primitive, in which case, interpolation will be done using adjacent
53 /// pose packed primitives which do have data for the particular joint.
54 ///
56 {
57 public:
58 
59 
60  // This is used to define the evaluation parameters for a call to the
61  // ::evaluate() function.
63  {
65  {
66  myRestAttribsToUnpack = nullptr;
67  myAnimAttribsToUnpack = nullptr;
68 
69  myUseLeftEndBehavior = false;
70  myLeftEndBehavior = GU_MotionClipEndBehavior::Clamp;
71 
72  myUseRightEndBehavior = false;
73  myRightEndBehavior = GU_MotionClipEndBehavior::Clamp;
74 
75  myResetMissingAttribs = false;
76  myConstantEvaluation = false;
77  myOutputTime = false;
78 
79  myRecomputeWorld = true;
80  myHierarchyCache = nullptr;
81 
82  myCenterOfMassName = "COM";
83  myCenterOfMassPtoff = GA_INVALID_OFFSET;
84  myConfigAttribName = "";
85  }
86 
87  // A filter which defines which point and detail attributes should be
88  // obtained from the topology.
90 
91  // A filter which defines which point and detail attributes should be
92  // obtained from the animated poses of the MotionClip.
94 
95  // Pairs of attributes which define the left and right end behaviors
96  // and whether to use the values from this class.
97  // If myUseLelfEndBehvaior is false, the left end behvaior of the
98  // MotionClip's clipinfo will be used instead.
103 
104  // If true, the point and detail attributes which exist on the input
105  // destination geometry, match the animated attribute filter, and
106  // do not exist on all of the animated poses used as the start of the
107  // blend will be reset or removed before evaluation. This ensures that
108  // the result of evaluating the MotionClip will remain the same for all
109  // filtered attributes, regardless of what the value of the attribtue
110  // was on the destination geometry prior to evalution.
112 
113  // If true, instead of linearly interpolating the poses, the
114  // interpolation mode will be constant.
116 
117  // If true, the time of the evaluation will be added as a point
118  // attribute to the evaluated pose.
120 
123 
124  // The name of the center of mass point and the point offset of the
125  // point in the result geometry.
126  // If the point offset is a valid offset for the result geometry,
127  // the point will be given transform and position attributes that
128  // correspond with the center of mass of the result point group. The
129  // center of mass point should not be in the result point group.
133  };
134 
135  /// clipinfo will override the gdp's clipinfo detail attribute
137  const GU_Detail *gdp,
138  UT_WorkBuffer &err_msg,
139  bool can_evaluate = true,
140  GU_MotionClipInfo *clipinfo = nullptr,
141  bool compute_default_clipinfo = false,
142  bool do_sort_samples = true,
143  bool enable_locking = true);
144 
145  virtual ~GU_MotionClipRO() = default;
146 
147  virtual bool updateGdp(const GU_Detail *gdp);
148 
149  /// Appends the unpacked toplogy geometry to dest
150  ///
151  void getTopology(fpreal &time, GU_Detail *dest,
152  const GA_AttributeFilter* skip = nullptr);
153 
154  bool hasTopology() const { return myHasTopology; }
155 
156  /// This will compute the frame at the given time, and
157  /// then copy the P+transform attributes of the ith
158  /// point in topologyPts into the ith point in resultPts.
159  ///
160  /// It will also include whatever extra attribs you request
161  /// as long as there is no current active GU_MotionClipBuilder
162  ///
163  /// @pre resultPts and topologyPts must correspond
164  /// to the same points in their respective
165  /// geometries, in the same order.
167  const GA_PointGroup *result_pts=nullptr,
168  const GA_PointGroup *topology_pts=nullptr,
169  const GA_AttributeFilter* extra_attribs_to_unpack=nullptr,
172  {
173  AutoLock lock(getLock());
174  myEvaluator.evaluate(time, result, result_pts,
175  getFrameDetail(-1), topology_pts, myHierarchyCache,
176  extra_attribs_to_unpack /*rest_attribs_to_unpack*/,
177  extra_attribs_to_unpack /*anim_attribs_to_unpack*/,
178  left_end_behavior, right_end_behavior,
179  false /*reset_missing_attribs*/,
180  false /*constant_evaluation*/,
181  false /*output_time*/,
182  true /*recompute_world*/,
183  nullptr /*is_anim_point_attrib*/,
184  GA_INVALID_OFFSET /*com_ptoff*/,
185  "" /*com_name*/,
186  "" /*config_attrib*/);
187  }
188 
189 
190  /// This will compute the frame at the given time, and
191  /// then copy the P+transform attributes of the ith
192  /// point in topologyPts into the ith point in resultPts.
193  ///
194  /// It will also include whatever extra attribs you request
195  /// as long as there is no current active GU_MotionClipBuilder
196  ///
197  /// The parameters used to define the interpolation must be set
198  /// by in an EvaluationParms structure.
199  ///
200  /// @pre resultPts and topologyPts must correspond
201  /// to the same points in their respective
202  /// geometries, in the same order.
203  ///
204  /// @pre is_anim_point_attribs returns whether each the requested point
205  /// attribute exists on the animated poses. An entry must already exist
206  /// for each attribtue in question.
208  const EvaluationParms &evaluation_parms,
209  const GA_PointGroup *result_pts=nullptr,
210  const GA_PointGroup *topology_pts=nullptr,
211  UT_ArrayStringMap<bool> *is_anim_point_attrib = nullptr)
212  {
213  AutoLock lock(getLock());
214 
215  GU_MotionClipEndBehavior left_end_behavior = myClipinfo.leftEndBehaviorEnum();
216  if (evaluation_parms.myUseLeftEndBehavior)
217  left_end_behavior = evaluation_parms.myLeftEndBehavior;
218 
219  GU_MotionClipEndBehavior right_end_behavior = myClipinfo.rightEndBehaviorEnum();
220  if (evaluation_parms.myUseRightEndBehavior)
221  right_end_behavior = evaluation_parms.myRightEndBehavior;
222 
223  GU_HierarchyCache *sopcache = evaluation_parms.myHierarchyCache;
224  if (!sopcache)
225  sopcache = &myHierarchyCache;
226 
227  myEvaluator.evaluate(time, result, result_pts,
228  getFrameDetail(-1), topology_pts, *sopcache,
229  evaluation_parms.myRestAttribsToUnpack,
230  evaluation_parms.myAnimAttribsToUnpack,
231  left_end_behavior, right_end_behavior,
232  evaluation_parms.myResetMissingAttribs,
233  evaluation_parms.myConstantEvaluation,
234  evaluation_parms.myOutputTime,
235  evaluation_parms.myRecomputeWorld,
236  is_anim_point_attrib,
237  evaluation_parms.myCenterOfMassPtoff,
238  evaluation_parms.myCenterOfMassName,
239  evaluation_parms.myConfigAttribName);
240  }
242  const EvaluationParms &evaluation_parms,
243  const GA_PointGroup *result_pts=nullptr,
244  const GA_PointGroup *topology_pts=nullptr,
245  UT_ArrayStringMap<bool> *is_anim_point_attrib = nullptr)
246  {
247  //AutoLock lock(getLock());
248 
249  GU_MotionClipEndBehavior left_end_behavior = myClipinfo.leftEndBehaviorEnum();
250  if (evaluation_parms.myUseLeftEndBehavior)
251  left_end_behavior = evaluation_parms.myLeftEndBehavior;
252 
253  GU_MotionClipEndBehavior right_end_behavior = myClipinfo.rightEndBehaviorEnum();
254  if (evaluation_parms.myUseRightEndBehavior)
255  right_end_behavior = evaluation_parms.myRightEndBehavior;
256 
257  GU_HierarchyCache *sopcache = evaluation_parms.myHierarchyCache;
258  if (!sopcache)
259  sopcache = &myHierarchyCache;
260 
261  myEvaluator.evaluate(time, result, result_pts,
262  getFrameDetail(-1), topology_pts, *sopcache,
263  evaluation_parms.myRestAttribsToUnpack,
264  evaluation_parms.myAnimAttribsToUnpack,
265  left_end_behavior, right_end_behavior,
266  evaluation_parms.myResetMissingAttribs,
267  evaluation_parms.myConstantEvaluation,
268  evaluation_parms.myOutputTime,
269  evaluation_parms.myRecomputeWorld,
270  is_anim_point_attrib,
271  evaluation_parms.myCenterOfMassPtoff,
272  evaluation_parms.myCenterOfMassName,
273  evaluation_parms.myConfigAttribName
274  );
275  }
276 
277  // This will re-compute the localtransforms of each frame in the
278  // evaluator so that each frame evaluates to the correct position
279  // while using the input scale inheritance for all joints
281  {
282  AutoLock lock(getLock());
283  myEvaluator.setScaleInheritance(getFrameDetail(-1),
284  scale_inheritance);
285  }
286  /// This computes the local transforms of each joint at the given
287  /// time. The ith element defines represents the ith joint in the
288  /// topology detail. getJointIndex can be used to check this
291  bool constant_evaluation=false)
292  {
293  AutoLock lock(getLock());
294 
295  UT_Array<GU_AgentXformD> *presult = nullptr;
296  UT_Array<UT_Matrix4D> *presult4 = nullptr;
297  myEvaluator.computeLocalTransforms(time, result, presult, presult4,
298  constant_evaluation);
299  if (presult!=nullptr)
300  result = *presult;
301  }
302 
303  /// Returns the index of the given joint name within the
304  /// topology detail
305  exint getJointIndex(const UT_StringHolder& joint_name) const
306  {
307  if (!myNameToJointIdx.contains(joint_name))
308  return -1;
309  return myNameToJointIdx.at(joint_name);
310  }
311 
312  /// Returns a point group of the topology detail based
313  /// on the given pattern
314  const GA_PointGroup* getJointGroup(
315  GOP_Manager &gop, const UT_StringHolder& pattern) const;
316  void getJointsInGroup(
317  GOP_Manager &gop, const UT_StringHolder& pattern,
318  UT_StringArray &joints_in_group) const;
319 
320  /// returns false if there was an error during initialization
321  ///
322  bool isInitialised() const
323  {
324  return myIsInitialised;
325  }
326 
327  exint numJoints() const
328  {
329  return myNumJoints;
330  }
331 
332  const GU_MotionClipInfo &clipInfo() const { return myClipinfo; }
333 
334  /// returns the sample at time, or nullptr if not found
335  const GU_Detail *getSample(fpreal time) const;
336  const GU_Detail *restFrame() const { return getFrameDetail(-1); }
337 
338  void getSortedFrameOrder(UT_Array<exint> &frame_order);
339 
341  return myEvaluator.getSampleTimes();
342  }
343 
344  bool canEvaluate() const {
345  return myCanEvaluate;
346  }
347 
348 protected:
350 
351  // Data Ids of the input geometry which were recorded for the purpose
352  // of determining if this GU_MotionClipRO class is still valid or if
353  // the geometry has changed too much.
355 
356  void sortPrimitives(GU_Detail *gdp, bool clear_array);
357 
358 private:
359  friend class GU_MotionClipRW;
360  friend class GU_MotionClipBuilder;
361 
362  /// Returns the time in seconds of the indexth frame
363  fpreal getFrameTime(exint index) const;
364  const GU_Detail* getFrameDetail(exint frame,
365  UT_Matrix4D *intrinsic=nullptr) const;
366  GA_Offset getFrameOffset(exint frame) const;
367 
368  /// Returns the highest frame index with a time
369  /// less than or equal to time or -1 if no such index exists
370  exint getFrameAtOrBefore(fpreal time) const;
371 
372  /// We use this class to separate the evaluation data
373  /// from the other members so that we can safely evaluate
374  /// while a MotionClipBuilder is manipulating the rest of
375  /// the object. This also makes it clear what data you
376  /// can skip updating when myCanEvaluate is false
377  ///
378  /// However if we need to unpack extra attributes we
379  /// need to find them within the gdp which is impossible
380  /// while there is a MotionClip builder operating on it...
381  /// Because of this we store a ptr to the clip and set it to
382  /// null whenever the Evaluator is out of date - when it is
383  /// null evaluate will skip unpacking attribs. The caller should
384  /// ensure that this is not allowed
385  class Evaluator
386  {
387  public:
388  Evaluator();
389 
390  void computeLocalTransforms(fpreal time,
392  UT_Array<GU_AgentXformD> *&presult,
393  UT_Array<UT_Matrix4D> *&presult4,
394  bool constant_evaluation);
395  void evaluate(fpreal target_time, GU_Detail *result,
396  const GA_PointGroup *result_pts,
397  const GU_Detail *topology,
398  const GA_PointGroup *topology_pts,
399  GU_HierarchyCache &sopcache,
400  const GA_AttributeFilter* rest_attribs_to_unpack,
401  const GA_AttributeFilter* anim_attribs_to_unpack,
402  GU_MotionClipEndBehavior left_end_behavior,
403  GU_MotionClipEndBehavior right_end_behavior,
404  bool reset_missing_attribs,
405  bool constant_evaluation,
406  bool output_time,
407  bool recompute_world,
408  UT_ArrayStringMap<bool> *is_anim_point_attrib,
409  const GA_Offset com_ptoff,
410  const UT_StringHolder com_name,
411  const UT_StringHolder config_attrib);
412  void setScaleInheritance(const GU_Detail *topology,
413  UT_ScaleInheritanceMode scale_inheritance);
414  void update(const GU_MotionClipRO &clip);
415  void setDirty()
416  {
417  myClip = nullptr;
418  }
419  const UT_Array<fpreal>& getSampleTimes() {
420  return myFrameTimes;
421  }
422 
423  private:
424  // A helper function for ::evaluate() which evaluates the extra detail
425  // attributes.
426  void evaluateDetailAttribs(GU_Detail *result,
427  const GU_Detail *topology,
428  const GU_Detail *detail_a,
429  const GU_Detail *detail_b,
430  const fpreal weight,
431  const GA_AttributeFilter &rest_filter,
432  const GA_AttributeFilter &anim_filter,
433  bool reset_missing_attribs);
434 
435  // A helper function for ::evaluaet() which resets the values of or
436  // removes attributes which exist on the result geometry, match the
437  // animated filter, and do not exist on at least one of the poses used
438  // as the start point of the blend.
439  // If result_pts is defined, the attribute is reset to its default value
440  // on those points.
441  // Otherwise, the attribute is destroyed (and may be re-created later in
442  // the evaluation process).
443  void resetMissingPointAttribs(GU_Detail *result,
444  const GA_PointGroup *result_pts,
445  const GU_Detail *topology,
446  const GA_AttributeFilter &rest_filter,
447  const GA_AttributeFilter &anim_filter,
448  bool output_time,
449  const UT_IntArray &start_poses,
450  UT_StringArray &whole_attrib_names);
451 
452  /// Returns the highest frame index with a time
453  /// less than or equal to time or -1 if no such index exists
454  exint getFrameAtOrBefore(fpreal time) const;
455 
456  /// myFrameTransforms[frame_idx][joint_idx] represents
457  /// joint_idx's decomposed local space transform in frame
458  /// frame_idx, even if the joint does not exist in the sample
459  UT_Array<UT_Array<GU_AgentXformD>> myFrameTransforms;
460  UT_Array<UT_Array<UT_Matrix4D>> myFrameTransforms4;
461 
462  /// myInterpFrames[frame_idx][joint_idx] contains a pair
463  /// containing the two sample indices used when interpolating
464  /// the position of this joint.
465  /// the first index will be strictly less than frame_idx
466  /// the second will be greater than or equal to frame_idx
468  UT_Array<fpreal> myFrameTimes;
469 
470  /// maps a joint name to the corresponding point offset
471  /// within each sample
472  UT_Array<UT_StringMap<GA_Offset>> myFrameJointOffsets;
473  fpreal myLastEvalTime;
474  exint myLastEvalFrame;
475  UT_Vector2R myClipRange;
476 
477  /// these are always outputted
478  GA_AttributeFilter myIsAttribExtra;
479 
480  // This is a flag to indicate whether the clearModel method has
481  // been called since the last time the evaluator was updated.
482  // This is needed so that the MotionClip can be evaluated properly.
483  bool myIsScaleInheritanceChanged;
484  UT_ScaleInheritanceMode myScaleInheritance;
485 
486  // We need the clip to fetch additional attributes. However
487  // we can not safely use it when the evaluator is dirty.
488  // We'll set this to null whenever it is unsafe to use
489  const GU_MotionClipRO *myClip;
490  };
491 
492  GU_MotionClipInfo generateClipInfo();
493 
494  Evaluator myEvaluator;
495 
496  GU_HierarchyCache myHierarchyCache;
497  GU_MotionClipInfo myClipinfo;
498 
499  class AutoLock : UT_NonCopyable
500  {
501  public:
502  AutoLock(UT_Lock *lock)
503  : myLock(lock)
504  {
505  if(myLock)
506  myLock->lock();
507  }
508 
509  ~AutoLock()
510  {
511  if (myLock)
512  myLock->unlock();
513  }
514 
515  private:
516  UT_Lock *myLock;
517  };
518 
519  UT_Lock myLock;
520  UT_Lock *getLock() { return myEnableLocking ? &myLock : nullptr; }
521  bool myEnableLocking;
522  bool myHasTopology;
523 
524  UT_Array<std::pair<GA_Offset, fpreal>> mySortedFrameOffsets;
525 
526  /// myUsedJoints[frame_idx][joint_idx] represents whether
527  /// joint_idx is is present in frame frame_idx
528  UT_Array<UT_BitArray> myUsedJoints;
529 
530  UT_StringMap<exint> myNameToJointIdx;
531 
532  exint myNumJoints;
533  exint myNumFrames;
534 
535  bool myIsInitialised;
536 
537  /// If we never evaluate we can skip a bunch of
538  /// slow useless computations (updating myEvaluator)
539  const bool myCanEvaluate;
540 };
541 
542 /// MotionClip object which allows for modifications
543 ///
544 /// You can add/remove frames by passing an instance of this
545 /// into GU_MotionBuilder
547 {
548 public:
549  friend class GU_MotionClipBuilder;
550 
552  GU_Detail *gdp,
553  UT_WorkBuffer &err_msg,
554  bool can_evaluate = true,
555  GU_MotionClipInfo *clipinfo = nullptr,
556  bool compute_default_clipinfo = false,
557  bool do_sort_samples = true,
558  bool enable_locking = true);
559 
560  ~GU_MotionClipRW() override = default;
561 
562  bool updateGdp(const GU_Detail *gdp) override { return false; }
564 
565  /// Sets the topology to the sample geometry,
566  /// marking the packed primitive with the given time attribute
567  ///
568  /// If there is already an existing topology sample must
569  /// contain only the same joints.
570  ///
571  /// The topology must be set before attempting to add frames
572  ///
573  /// returns false on error
574  bool setTopology(fpreal time, const GU_Detail *sample,
575  UT_WorkBuffer &error_msg);
576 
577  /// This will add a clipinfo detail attribute based on the primitive times
578  void addClipInfo();
579 
580 private:
582  {
583  // the const cast should be safe because an instance of
584  // GU_MotionClipRW can only be created with a non-const gdp
585  return SYSconst_cast(ourGdp);
586  }
587 
588 };
589 
590 /// Used to make a batch of modifications to a motion clip.
591 ///
592 /// It will store the changes in the clip object and then flush
593 /// them to the clip's evaluator when it is destroyed
594 ///
595 /// Each call to add/removeSample will update the clip's GDP, etc
596 /// but the evaluator's internal data structures will not
597 /// be updated until the flush - so we can safely keep evaluating the
598 /// the clip which we are adding frames, but the new frames will not
599 /// be reflected in the evaluated animation until this object is destroyed
600 ///
601 /// Note that the evaluator will not be able to unpack attributes until
602 /// this is destructed
604 {
605 public:
606  /// @pre Clip must outlive this instance
607  ///
609  : myClip(clip) {}
610 
611  /// This will update clip to store the new samples
612  ///
614 
615  /// Adds a sample/keyframe into the clip at the given time
616  ///
617  /// If the a sample at the given time exists it will be replaced
618  /// returns false on error
619  ///
620  /// @pre Each point's name attrib must correspond to one
621  /// of the topology's joint names
622  /// @pre Sample must either provide a localtransform attribute
623  /// or have the same topology as our class so we can compute it
624  bool addSample(fpreal time, const GU_Detail *sample,
625  UT_WorkBuffer &error_msg,
626  GA_AttributeFilter extra_attribs,
627  const GA_PointGroup *pts = nullptr,
628  bool recompute_local = false,
629  bool is_key_pose = false,
630  const UT_StringHolder key_pose_attrib="");
631 
632  /// Removes all samples within a given inclusive time range.
633  /// Returns false on error
634  bool removeSamples(UT_Vector2R range, UT_WorkBuffer &error_msg);
635 
636  /// Removes the sample at time
637  ///
638  /// returns false on error/missing sample
639  bool removeSample(fpreal time, UT_WorkBuffer &error_msg);
640 
641 private:
642  GU_MotionClipRW *myClip;
643 };
644 
645 #endif
GU_HierarchyCache * myHierarchyCache
virtual bool updateGdp(const GU_Detail *gdp)
bool canEvaluate() const
bool hasTopology() const
GLenum GLint * range
Definition: glcorearb.h:1925
void skip(T &in, int n)
Definition: ImfXdr.h:711
GT_API const UT_StringHolder time
SYS_FORCE_INLINE T * SYSconst_cast(const T *foo)
Definition: SYS_Types.h:136
int64 exint
Definition: SYS_Types.h:125
**But if you need a result
Definition: thread.h:613
void computeLocalTransforms(fpreal time, UT_Array< GU_AgentXformD > &result, bool constant_evaluation=false)
#define GA_INVALID_OFFSET
Definition: GA_Types.h:678
const GU_Detail * ourGdp
GA_Size GA_Offset
Definition: GA_Types.h:641
void evaluateNoLock(fpreal time, GU_Detail *result, const EvaluationParms &evaluation_parms, const GA_PointGroup *result_pts=nullptr, const GA_PointGroup *topology_pts=nullptr, UT_ArrayStringMap< bool > *is_anim_point_attrib=nullptr)
const UT_Array< fpreal > & getSampleTimes()
const GU_MotionClipInfo & clipInfo() const
friend class GU_MotionClipRW
const GA_AttributeFilter * myAnimAttribsToUnpack
Definition: GU_MotionClip.h:93
bool updateGdp(const GU_Detail *gdp) override
GU_MotionClipEndBehavior
GU_MotionClipDataIds ourDataIds
void evaluate(fpreal time, GU_Detail *result, const EvaluationParms &evaluation_parms, const GA_PointGroup *result_pts=nullptr, const GA_PointGroup *topology_pts=nullptr, UT_ArrayStringMap< bool > *is_anim_point_attrib=nullptr)
GT_API const UT_StringHolder topology
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
bool updateGdpNC(GU_Detail *gdp)
#define GU_API
Definition: GU_API.h:14
GLushort pattern
Definition: glad.h:2583
exint getJointIndex(const UT_StringHolder &joint_name) const
exint numJoints() const
void setScaleInheritance(UT_ScaleInheritanceMode scale_inheritance)
const GA_AttributeFilter * myRestAttribsToUnpack
Definition: GU_MotionClip.h:89
fpreal64 fpreal
Definition: SYS_Types.h:277
GLuint index
Definition: glcorearb.h:786
void evaluate(fpreal time, GU_Detail *result, const GA_PointGroup *result_pts=nullptr, const GA_PointGroup *topology_pts=nullptr, const GA_AttributeFilter *extra_attribs_to_unpack=nullptr, GU_MotionClipEndBehavior left_end_behavior=GU_MotionClipEndBehavior::Clamp, GU_MotionClipEndBehavior right_end_behavior=GU_MotionClipEndBehavior::Clamp)
const GU_Detail * restFrame() const
GU_MotionClipEndBehavior myLeftEndBehavior
UT_ScaleInheritanceMode
Scale inheritance modes.
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T clip(const T &p, const Box< T > &box) IMATH_NOEXCEPT
Definition: ImathBoxAlgo.h:29
bool isInitialised() const
GU_MotionClipEndBehavior myRightEndBehavior
GU_MotionClipBuilder(GU_MotionClipRW *clip)