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:
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 #include <UT/UT_Assert.h>
18 #include <UT/UT_Options.h>
19 #include <UT/UT_Vector2.h>
20 #include <SYS/SYS_Math.h>
21 #include <SYS/SYS_Types.h>
22 
23 class GEO_Detail;
24 class GU_Detail;
25 
27 {
28  Clamp = 0,
29  Loop = 1,
30  Mirror = 2
31 };
32 
33 /// Returns true if target_rate needs interpolation into source_rate
34 inline bool
35 GUsampleRatesNeedInterpolation(fpreal target_rate, fpreal source_rate)
36 {
37  // No interpolation needed if rates match
38  // NOTE: Use high tolerance here because we're comparing FPS values
39  if (SYSisEqual(target_rate, source_rate, 1e-2))
40  return false;
41 
42  // Needs interpolation when target_rate is faster because source has less
43  // samples.
44  if (target_rate > source_rate)
45  return true;
46 
47  // When source_rate is faster, then only needs to interpolate if it doesn't
48  // divide evenly.
49  return !SYSequalZero(SYSfmod(source_rate, target_rate));
50 }
51 
52 /// Mapper class for conversion between clip and scene time (in seconds)
54 {
55 public:
56 
57  /// Reset to the default scene's global range, unclamped.
58  void reset() { *this = GU_MotionClipTimeMap{}; }
59 
60  /// Start time in clip seconds
61  /// @{
62  fpreal start() const
63  { return myStart; }
64  void setStart(fpreal v, bool clamp = true)
65  { myStart = v; myClampStart = clamp; }
66  /// This variant will first clamp v to existing parameters
67  void setClampedStart(fpreal v, bool clamp = true)
68  { myStart = clampClipSeconds(v); myClampStart = clamp; }
69  /// @}
70 
71  /// End time to clamp to in clip seconds
72  /// @{
73  fpreal end() const
74  { return myEnd; }
75  void setEnd(fpreal v, bool clamp = true)
76  { myEnd = v; myClampEnd = clamp; }
77  /// This variant will first clamp v to existing parameters
78  void setClampedEnd(fpreal v, bool clamp = true)
79  { myEnd = clampClipSeconds(v); myClampEnd = clamp; }
80  /// @}
81 
82  /// Trim the current range to the given (assumes we have valid range)
83  void trimRange(fpreal start, fpreal end);
84 
85  /// Returns true when we have both start/end and start > end
86  bool hasInvalidRange() const { return (myStart > myEnd); }
87 
88  /// Playback start time in scene seconds
89  /// @{
90  fpreal playbackStart() const { return myPlaybackStart; }
91  void setPlaybackStart(fpreal v) { myPlaybackStart = v; }
92  /// @}
93 
94  /// Speed at which to playback in the scene
95  /// @{
96  fpreal speed() const { return mySpeed; }
97  void setSpeed(fpreal v) { mySpeed = v; }
98  /// @}
99 
100  /// Convert from clip time to scene time
101  fpreal toSceneSeconds(fpreal clip_seconds) const;
102 
103  /// Convert from scene time to clip time
104  fpreal toClipSeconds(fpreal scene_seconds) const;
105 
106  /// Clamp clip time depending to available clip range
107  fpreal clampClipSeconds(fpreal clip_seconds) const;
108 
109 private:
110  /// clip time origin in seconds
111  fpreal myStart = CHgetManager()->getGlobalStart();
112 
113  /// max clip time in seconds
114  fpreal myEnd = CHgetManager()->getGlobalEnd();
115 
116  /// scene time origin in seconds
117  fpreal myPlaybackStart = CHgetManager()->getGlobalStart();
118 
119  /// scene playback speed
120  fpreal mySpeed = 1.0;
121 
122  bool myClampStart = false; /// clamp to start time?
123  bool myClampEnd = false; /// clamp to end time?
124 };
125 
127 {
128 public:
129  GU_MotionClipInfo() = default;
130 
131  /// Reset to default constructed state
132  void reset() { *this = GU_MotionClipInfo{}; }
133 
134  /// Initialize from given ClipTimeMap, filling in missing information
135  /// from CHgetManager() as required.
136  void initFromTimeMap(
137  const GU_MotionClipTimeMap& time_map,
138  fpreal source_rate);
139 
140  /// Load values from geometry
141  bool load(const GEO_Detail& geo);
142 
143  /// Save values to geometry
144  bool save(GEO_Detail& geo);
145 
146  /// Get name of clipinfo detail attribute
147  static UT_StringHolder attribName();
148 
149  /// Source clip range in seconds
150  /// @{
151  const UT_Vector2R& sourceRange() const { return mySourceRange; }
153  { mySourceRange = UT_Vector2R{start, end}; }
154  /// @}
155 
156  /// Source clip rate in frames per second
157  /// @{
158  fpreal sourceRate() const { return mySourceRate; }
160  { mySourceRate = rate; }
161  /// @}
162 
163  /// Scene clip range in seconds
164  /// @{
165  UT_Vector2R& range() { return myRange; }
166  const UT_Vector2R& range() const { return myRange; }
168  { myRange = UT_Vector2R{start, end}; }
169  /// @}
170 
171  /// Scene rate in frames per second
172  /// @{
173  fpreal rate() const { return myRate; }
174  void setRate(fpreal rate) { myRate = rate; }
175  /// @}
176 
177  /// Name of the clip.
178  /// @{
179  const UT_StringHolder &name() const { return myName; }
181  { myName = name; }
182 
183  /// The end behavior should the clip be evaluate after the last frame
184  /// @{
186  { return myRightEndBehavior; }
187  GU_MotionClipEndBehavior rightEndBehaviorEnum() const;
188 
189  void setRightEndBehavior(const UT_StringHolder &behavior);
190  /// @}
191  /// @}
192 
193  /// The end behavior should the clip be evaluated before the first frame
194  /// @{
196  { return myLeftEndBehavior; }
197  GU_MotionClipEndBehavior leftEndBehaviorEnum() const;
198 
199  void setLeftEndBehavior(const UT_StringHolder &behavior);
200  /// @}
201  /// @}
202  /// @}
203 
204 private:
205  GU_MotionClipEndBehavior getEndBehaviorFromString(const UT_StringHolder &behavior) const;
206 
207  UT_Vector2R mySourceRange; // source range in secs
208  fpreal mySourceRate; // source sampling rate
209  UT_Vector2R myRange{0,0}; // anim range in seconds
210  fpreal myRate{0}; // anim sampling rate
211  UT_StringHolder myName; // anim clip name
212 
213  // right end behavior
214  bool myRightEndBehaviorUsed{false};
215  UT_StringHolder myRightEndBehavior{""};
216 
217  // left end behavior
218  bool myLeftEndBehaviorUsed{false};
219  UT_StringHolder myLeftEndBehavior{""};
220 };
221 
222 /// Map between channel names and the attributes that the channel values are
223 /// stored in.
225 {
226 public:
227  /// Returns whether there are any channels in the map.
228  bool isEmpty() const { return myOptions.isEmpty(); }
229 
230  /// Load the channel map from a detail attribute.
231  bool load(const GU_Detail& detail);
232 
233  /// Save the channel map as a detail attribute.
234  bool save(GU_Detail& detail) const;
235 
236  /// Returns a sorted list of the channel names.
237  UT_StringArray channelNames() const;
238 
239  /// Returns the channel's value, using the attribute specified in the map.
240  fpreal getChannelValue(
241  const GU_Detail& detail,
242  const UT_StringHolder& channel_name) const;
243 
244  /// Add a channel where the value is provided by a detail attribute.
245  void addDetailAttrib(
246  const UT_StringHolder& channel_name,
247  const UT_StringHolder& attrib_name);
248 
249  /// Add a channel where the value is provided by a point attribute's value
250  /// for a specific joint.
251  void addPointAttrib(
252  const UT_StringHolder& attrib_name,
253  const UT_StringHolder& joint_name);
254 
255 private:
256  UT_OptionsHolder myOptions;
257 };
258 
259 namespace GU_MotionClipNames
260 {
261  /// Attribute storing the channel name that provides the shape's weight.
263  /// Attribute storing the unique name of the blendshape input.
265 }
266 
267 ///////////////////////////////////////////////////////////////////////////////
268 //
269 // Inline Implementations
270 //
271 
272 inline void
274 {
275  if (myStart < start)
276  myStart = start;
277  if (myEnd > end)
278  myEnd = end;
279 }
280 
281 inline fpreal
283 {
285  if (myClampStart && clip_seconds < myStart)
286  clip_seconds = myStart;
287  else if (myClampEnd && clip_seconds > myEnd)
288  clip_seconds = myEnd;
289  return clip_seconds;
290 }
291 
292 inline fpreal
294 {
295  fpreal t = clampClipSeconds(clip_seconds);
296  return (t - myStart)/mySpeed + myPlaybackStart;
297 }
298 
299 inline fpreal
301 {
302  fpreal t = (scene_seconds - myPlaybackStart)*mySpeed;
303  return clampClipSeconds(t + myStart);
304 }
305 
306 #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_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 setSpeed(fpreal v)
GLuint const GLchar * name
Definition: glew.h:1814
void setClampedStart(fpreal v, bool clamp=true)
This variant will first clamp v to existing parameters.
const UT_Vector2R & sourceRange() const
void setSourceRange(fpreal start, fpreal end)
fpreal toClipSeconds(fpreal scene_seconds) const
Convert from scene time to clip time.
void reset()
Reset to default constructed state.
fpreal sourceRate() const
void setPlaybackStart(fpreal v)
const GLdouble * v
Definition: glew.h:1391
Mapper class for conversion between clip and scene time (in seconds)
UT_StringHolder rightEndBehavior() const
const UT_StringHolder & name() const
fpreal speed() const
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.
fpreal toSceneSeconds(fpreal clip_seconds) const
Convert from clip time to scene time.
CH_Manager * CHgetManager()
Definition: CH_Manager.h:1742
fpreal getGlobalStart() const
Definition: CH_Manager.h:998
GU_MotionClipEndBehavior
GLenum clamp
Definition: glew.h:2166
fpreal clampClipSeconds(fpreal clip_seconds) const
Clamp clip time depending to available clip range.
void setRate(fpreal rate)
GLuint GLuint end
Definition: glew.h:1253
UT_Vector2R & range()
fpreal getGlobalEnd() const
Definition: CH_Manager.h:999
#define GU_API
Definition: GU_API.h:14
void setName(const UT_StringHolder &name)
GLuint start
Definition: glew.h:1253
bool isEmpty() const
Returns whether there are any channels in the map.
void setStart(fpreal v, bool clamp=true)
bool SYSequalZero(const UT_Vector3T< T > &v)
Definition: UT_Vector3.h:848
bool GUsampleRatesNeedInterpolation(fpreal target_rate, fpreal source_rate)
Returns true if target_rate needs interpolation into source_rate.
void setRange(fpreal start, fpreal end)
fpreal64 fpreal
Definition: SYS_Types.h:277
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:135
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.
GLdouble GLdouble t
Definition: glew.h:1398