HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_MotionClipUtil.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_MotionClipUtil.h (GU Library, C++)
7  *
8  * COMMENTS: Utility methods for working with motion clips
9  */
10 
11 #ifndef __GU_MOTIONCLIPUTIL_H_INCLUDED__
12 #define __GU_MOTIONCLIPUTIL_H_INCLUDED__
13 
14 #include "GU_API.h"
15 
16 #include <CH/CH_Manager.h>
17 
18 #include <GA/GA_Types.h>
19 
20 #include <UT/UT_Assert.h>
21 #include <UT/UT_Options.h>
22 #include <UT/UT_Vector2.h>
23 
24 #include <SYS/SYS_Math.h>
25 #include <SYS/SYS_Types.h>
26 
27 class GEO_Detail;
28 class GU_Detail;
29 
31 {
32  Clamp = 0,
33  Loop = 1,
34  Mirror = 2
35 };
36 
37 /// Returns true if target_rate needs interpolation into source_rate
38 inline bool
39 GUsampleRatesNeedInterpolation(fpreal target_rate, fpreal source_rate)
40 {
41  // No interpolation needed if rates match
42  // NOTE: Use high tolerance here because we're comparing FPS values
43  if (SYSisEqual(target_rate, source_rate, 1e-2))
44  return false;
45 
46  // Needs interpolation when target_rate is faster because source has less
47  // samples.
48  if (target_rate > source_rate)
49  return true;
50 
51  // When source_rate is faster, then only needs to interpolate if it doesn't
52  // divide evenly.
53  return !SYSequalZero(SYSfmod(source_rate, target_rate));
54 }
55 
56 /// Mapper class for conversion between clip and scene time (in seconds)
58 {
59 public:
60 
61  /// Reset to the default scene's global range, unclamped.
62  void reset() { *this = GU_MotionClipTimeMap{}; }
63 
64  /// Start time in clip seconds
65  /// @{
66  fpreal start() const
67  { return myStart; }
68  void setStart(fpreal v, bool clamp = true)
69  { myStart = v; myClampStart = clamp; }
70  /// This variant will first clamp v to existing parameters
71  void setClampedStart(fpreal v, bool clamp = true)
72  { myStart = clampClipSeconds(v); myClampStart = clamp; }
73  /// @}
74 
75  /// End time to clamp to in clip seconds
76  /// @{
77  fpreal end() const
78  { return myEnd; }
79  void setEnd(fpreal v, bool clamp = true)
80  { myEnd = v; myClampEnd = clamp; }
81  /// This variant will first clamp v to existing parameters
82  void setClampedEnd(fpreal v, bool clamp = true)
83  { myEnd = clampClipSeconds(v); myClampEnd = clamp; }
84  /// @}
85 
86  /// Trim the current range to the given (assumes we have valid range)
87  void trimRange(fpreal start, fpreal end);
88 
89  /// Returns true when we have both start/end and start > end
90  bool hasInvalidRange() const { return (myStart > myEnd); }
91 
92  /// Playback start time in scene seconds
93  /// @{
94  fpreal playbackStart() const { return myPlaybackStart; }
95  void setPlaybackStart(fpreal v) { myPlaybackStart = v; }
96  /// @}
97 
98  /// Speed at which to playback in the scene
99  /// @{
100  fpreal speed() const { return mySpeed; }
101  void setSpeed(fpreal v) { mySpeed = v; }
102  /// @}
103 
104  /// Convert from clip time to scene time
105  fpreal toSceneSeconds(fpreal clip_seconds) const;
106 
107  /// Convert from scene time to clip time
108  fpreal toClipSeconds(fpreal scene_seconds) const;
109 
110  /// Clamp clip time depending to available clip range
111  fpreal clampClipSeconds(fpreal clip_seconds) const;
112 
113 private:
114  /// clip time origin in seconds
115  fpreal myStart = CHgetManager()->getGlobalStart();
116 
117  /// max clip time in seconds
118  fpreal myEnd = CHgetManager()->getGlobalEnd();
119 
120  /// scene time origin in seconds
121  fpreal myPlaybackStart = CHgetManager()->getGlobalStart();
122 
123  /// scene playback speed
124  fpreal mySpeed = 1.0;
125 
126  bool myClampStart = false; /// clamp to start time?
127  bool myClampEnd = false; /// clamp to end time?
128 };
129 
131 {
132 public:
133  GU_MotionClipInfo() = default;
134 
135  /// Reset to default constructed state
136  void reset() { *this = GU_MotionClipInfo{}; }
137 
138  /// Initialize from given ClipTimeMap, filling in missing information
139  /// from CHgetManager() as required.
140  void initFromTimeMap(
141  const GU_MotionClipTimeMap& time_map,
142  fpreal source_rate);
143 
144  /// Load values from geometry
145  bool load(const GEO_Detail& geo);
146 
147  /// Save values to geometry
148  bool save(GEO_Detail& geo);
149 
150  /// Get name of clipinfo detail attribute
151  static UT_StringHolder attribName();
152 
153  /// Source clip range in seconds
154  /// @{
155  const UT_Vector2R& sourceRange() const { return mySourceRange; }
157  { mySourceRange = UT_Vector2R{start, end}; }
158  /// @}
159 
160  /// Source clip rate in frames per second
161  /// @{
162  fpreal sourceRate() const { return mySourceRate; }
164  { mySourceRate = rate; }
165  /// @}
166 
167  /// Scene clip range in seconds
168  /// @{
169  UT_Vector2R& range() { return myRange; }
170  const UT_Vector2R& range() const { return myRange; }
172  { myRange = UT_Vector2R{start, end}; }
173  /// @}
174 
175  /// Scene rate in frames per second
176  /// @{
177  fpreal rate() const { return myRate; }
178  void setRate(fpreal rate) { myRate = rate; }
179  /// @}
180 
181  /// Name of the clip.
182  /// @{
183  const UT_StringHolder &name() const { return myName; }
184  void setName(const UT_StringHolder &name)
185  /// @}
186  { myName = name; }
187 
188  /// SOP path used to create the clip.
189  /// @{
190  const UT_StringHolder &sopPath() const { return mySopPath; }
191  void setSopPath(const UT_StringHolder &path);
192  /// @}
193 
194  /// The end behavior should the clip be evaluate after the last frame
195  /// @{
197  { return myRightEndBehavior; }
198  GU_MotionClipEndBehavior rightEndBehaviorEnum() const;
199 
200  void setRightEndBehavior(const UT_StringHolder &behavior);
201  void setRightEndBehavior(const GU_MotionClipEndBehavior &behavior);
202  /// @}
203  /// @}
204 
205  /// The end behavior should the clip be evaluated before the first frame
206  /// @{
208  { return myLeftEndBehavior; }
209  GU_MotionClipEndBehavior leftEndBehaviorEnum() const;
210 
211  void setLeftEndBehavior(const UT_StringHolder &behavior);
212  void setLeftEndBehavior(const GU_MotionClipEndBehavior &behavior);
213  /// @}
214  /// @}
215  /// @}
216 
217  bool operator==(const GU_MotionClipInfo& other) const
218  {
219  return mySourceRange == other.mySourceRange
220  && mySourceRate == other.mySourceRate
221  && myRange == other.myRange
222  && myRate == other.myRate
223  && myName == other.myName
224  && mySopPathUsed == other.mySopPathUsed
225  && mySopPath == other.mySopPath
226  && myRightEndBehaviorUsed == other.myRightEndBehaviorUsed
227  && myRightEndBehavior == other.myRightEndBehavior
228  && myLeftEndBehaviorUsed == other.myLeftEndBehaviorUsed
229  && myLeftEndBehavior == other.myLeftEndBehavior;
230  }
231 
232  bool operator!=(const GU_MotionClipInfo& other) const
233  {
234  return (!operator==(other));
235  }
236 
237 private:
238  GU_MotionClipEndBehavior getEndBehaviorFromString(const UT_StringHolder &behavior) const;
239  UT_StringHolder getStringFromEndBehavior(
240  const GU_MotionClipEndBehavior &behavior) const;
241 
242  UT_Vector2R mySourceRange{0,0}; // source range in secs
243  fpreal mySourceRate{0.0}; // source sampling rate
244  UT_Vector2R myRange{0,0}; // anim range in seconds
245  fpreal myRate{0.0}; // anim sampling rate
246  UT_StringHolder myName; // anim clip name
247  UT_StringHolder mySopPath; // anim clip path
248  bool mySopPathUsed{false};
249 
250  // right end behavior
251  bool myRightEndBehaviorUsed{false};
252  UT_StringHolder myRightEndBehavior{""};
253 
254  // left end behavior
255  bool myLeftEndBehaviorUsed{false};
256  UT_StringHolder myLeftEndBehavior{""};
257 };
258 
259 /// Map between channel names and the attributes that the channel values are
260 /// stored in.
262 {
263 public:
264  /// Returns whether there are any channels in the map.
265  bool isEmpty() const { return myOptions.isEmpty(); }
266 
267  /// Load the channel map from a detail attribute.
268  bool load(const GU_Detail& detail);
269 
270  /// Save the channel map as a detail attribute.
271  bool save(GU_Detail& detail) const;
272 
273  /// Returns a sorted list of the channel names.
274  UT_StringArray channelNames() const;
275 
276  /// Returns the channel's value, using the attribute specified in the map.
277  fpreal getChannelValue(
278  const GU_Detail& detail,
279  const UT_StringHolder& channel_name) const;
280 
281  /// Add a channel where the value is provided by a detail attribute.
282  void addDetailAttrib(
283  const UT_StringHolder& channel_name,
284  const UT_StringHolder& attrib_name);
285 
286  /// Add a channel where the value is provided by a point attribute's value
287  /// for a specific joint.
288  void addPointAttrib(
289  const UT_StringHolder& attrib_name,
290  const UT_StringHolder& joint_name);
291 
292 private:
293  UT_OptionsHolder myOptions;
294 };
295 
296 // Keeps track of and compares the data ids of details that are important for
297 // the evaluation of motion clips.
299 {
300 public:
301  GU_MotionClipDataIds(const GU_Detail *gdp);
303 
304  bool update(const GU_Detail *gdp, bool &did_change);
305 
306 private:
307  GA_DataId myPrimitivesId;
308  GA_DataId myTopologyId;
309  GA_DataId myTimeAttribId;
310  GA_DataId myClipInfoAttribId;
311 };
312 
313 namespace GU_MotionClipNames
314 {
315  /// Attribute storing the channel name that provides the shape's weight.
317  /// Attribute storing the unique name of the blendshape input.
319  /// Attribute storing the name of a blendshape inbetween
321  /// Attribute storing the weight position of a blendshape inbetween
323 }
324 
325 ///////////////////////////////////////////////////////////////////////////////
326 //
327 // Inline Implementations
328 //
329 
330 inline void
332 {
333  if (myStart < start)
334  myStart = start;
335  if (myEnd > end)
336  myEnd = end;
337 }
338 
339 inline fpreal
341 {
343  if (myClampStart && clip_seconds < myStart)
344  clip_seconds = myStart;
345  else if (myClampEnd && clip_seconds > myEnd)
346  clip_seconds = myEnd;
347  return clip_seconds;
348 }
349 
350 inline fpreal
352 {
353  fpreal t = clampClipSeconds(clip_seconds);
354  return (t - myStart)/mySpeed + myPlaybackStart;
355 }
356 
357 inline fpreal
359 {
360  fpreal t = (scene_seconds - myPlaybackStart)*mySpeed;
361  return clampClipSeconds(t + myStart);
362 }
363 
364 #endif // __GU_MOTIONCLIPUTIL_H_INCLUDED__
fpreal start() const
fpreal rate() const
UT_StringHolder leftEndBehavior() const
bool hasInvalidRange() const
Returns true when we have both start/end and start > end.
const UT_StringHolder & sopPath() const
const UT_Vector2R & range() const
fpreal playbackStart() const
void setSourceRate(fpreal rate)
void setClampedEnd(fpreal v, bool clamp=true)
This variant will first clamp v to existing parameters.
void setClampedStart(fpreal v, bool clamp=true)
This variant will first clamp v to existing parameters.
GLenum clamp
Definition: glcorearb.h:1234
const UT_Vector2R & sourceRange() const
void setSourceRange(fpreal start, fpreal end)
fpreal toClipSeconds(fpreal scene_seconds) const
Convert from scene time to clip time.
int64 GA_DataId
Definition: GA_Types.h:686
GLuint start
Definition: glcorearb.h:475
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
void reset()
Reset to default constructed state.
fpreal sourceRate() const
void setPlaybackStart(fpreal v)
GLuint const GLchar * name
Definition: glcorearb.h:786
Mapper class for conversion between clip and scene time (in seconds)
UT_StringHolder rightEndBehavior() const
const UT_StringHolder & name() const
GLdouble GLdouble t
Definition: glew.h:1403
GU_API const UT_StringHolder blendshape_channel
Attribute storing the channel name that provides the shape's weight.
GU_API const UT_StringHolder blendshape_name
Attribute storing the unique name of the blendshape input.
GU_API const UT_StringHolder blendshape_inbetween_name
Attribute storing the name of a blendshape inbetween.
fpreal toSceneSeconds(fpreal clip_seconds) const
Convert from clip time to scene time.
CH_Manager * CHgetManager()
Definition: CH_Manager.h:1840
fpreal getGlobalStart() const
Definition: CH_Manager.h:1020
GU_MotionClipEndBehavior
fpreal clampClipSeconds(fpreal clip_seconds) const
Clamp clip time depending to available clip range.
void setRate(fpreal rate)
bool operator==(const GU_MotionClipInfo &other) const
const GLdouble * v
Definition: glcorearb.h:837
GLuint GLuint end
Definition: glcorearb.h:475
UT_Vector2R & range()
fpreal getGlobalEnd() const
Definition: CH_Manager.h:1021
#define GU_API
Definition: GU_API.h:14
bool isEmpty() const
Returns whether there are any channels in the map.
GU_API const UT_StringHolder blendshape_inbetween_weight
Attribute storing the weight position of a blendshape inbetween.
void setStart(fpreal v, bool clamp=true)
bool SYSequalZero(const UT_Vector3T< T > &v)
Definition: UT_Vector3.h:1051
bool GUsampleRatesNeedInterpolation(fpreal target_rate, fpreal source_rate)
Returns true if target_rate needs interpolation into source_rate.
void setRange(fpreal start, fpreal end)
bool operator!=(const GU_MotionClipInfo &other) const
fpreal64 fpreal
Definition: SYS_Types.h:277
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:153
void setEnd(fpreal v, bool clamp=true)
void trimRange(fpreal start, fpreal end)
Trim the current range to the given (assumes we have valid range)
void reset()
Reset to the default scene's global range, unclamped.