HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_AgentRig.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_AgentRig.h (GU Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GU_AgentRig__
12 #define __GU_AgentRig__
13 
14 #include "GU_API.h"
15 
16 #include "GU_AgentXform.h"
17 
18 #include <UT/UT_Array.h>
19 #include <UT/UT_Assert.h>
20 #include <UT/UT_IntrusivePtr.h>
21 #include <UT/UT_Matrix4.h>
22 #include <UT/UT_StackBuffer.h>
23 #include <UT/UT_StringArray.h>
24 #include <UT/UT_StringHolder.h>
25 #include <UT/UT_StringMap.h>
26 #include <UT/UT_ValArray.h>
27 
28 
29 class UT_JSONParser;
30 class UT_JSONWriter;
31 
35 
36 
37 /// A rig for the agent primitive
38 class GU_API GU_AgentRig : public UT_IntrusiveRefCounter<GU_AgentRig>
39 {
40 public:
47 
48  static GU_AgentRigPtr addRig(const UT_StringHolder &name);
49  static GU_AgentRigPtr addRigFromFile(
51  UT_StringArray &errors);
52  /// Creates a copy of the rig. The copy will not be marked as an external
53  /// reference.
54  static GU_AgentRigPtr addRigCopy(const GU_AgentRig &src);
55 
56 private:
57  // Use the static addRig() method to create new rigs
58  GU_AgentRig(const UT_StringHolder &name, bool is_file);
59 
60 public:
61  ~GU_AgentRig();
62 
63  /// Construct using flat arrays.
64  /// - @c names: The array of names for each transform (one per transform)
65  /// - @c child_counts: An array of child counts for each transform
66  /// Should have the same number of entries as the @c names array
67  /// - @c children: An array of children. This is the concatenation of all
68  /// the child indices for each transform. There should be
69  /// @c sum(child_counts) entries in this array.
70  bool construct(
71  const UT_StringArray& names,
72  const UT_IntArray& child_counts,
73  const UT_IntArray& children);
74 
75  int64 getMemoryUsage(bool inclusive) const;
76 
77  /// Unique ID of the rig.
78  exint getUniqueId() const { return myUniqueId; }
79 
80  /// @{
81  /// The name of the rig (or filename, if loaded from disk).
82  const UT_StringHolder &name() const
83  { return myName; }
85  { myName = name; }
86  ///
87 
88  /// Return whether the rig was loaded from disk.
89  bool isFile() const
90  { return myIsFile; }
91  /// Clear the flag marking that the rig references a file on disk.
92  void clearIsFile();
93 
94  /// Clear the rig
95  void clear();
96 
97  /// Check validity of rig
98  bool checkValid() const;
99 
100  /// Return number of transforms
102  { return myTransforms.entries(); }
103  /// Return the name of the given transform
105  { return myTransforms(i); }
106  /// Return the parent of the given transform (or -1 for the root)
108  { return myParents(i); }
109  /// Return the number of children for the given transform
111  {
112  return myChildStarts(i+1) - myChildStarts(i);
113  }
114  /// Return the Nth child for the given transform
116  {
117  UT_ASSERT_P(child < childCount(transform));
118  return myChildren(myChildStarts(transform) + child);
119  }
120  /// Return the root transform(s) of the rig.
121  const UT_IntArray &roots() const
122  { return myRoots; }
123 
124  /// Find a transform by name. Returns -1 for an invalid name
125  exint findTransform(const UT_StringRef &name) const;
126 
127  /// Returns the rest local transform for the specified joint.
129  { return myRestLocalXforms[i]; }
130  /// Returns the rest world transform for the specified joint.
132  { return myRestWorldXforms[i]; }
133  /// Updates the rest transforms for the rig (in local space).
134  bool setRestLocalTransforms(const UT_Array<Xform> &xforms);
135 
136  /// Save a rig
137  bool save(UT_JSONWriter& w) const;
138  /// Load a rig
139  bool load(UT_JSONParser& p, UT_StringArray& errors);
140 
141  /// Dump to stdout for debugging
142  void dump() const;
143 
144  /// Iterator for top down traversal of the rig hierarchy. Each visited
145  /// transform's parent is guaranteed to be visited before its children.
147  {
148  public:
149  const_iterator(const GU_AgentRig &rig, int start = -1)
150  : myRig(rig), myIndex(0), myEnd(0), myQueue(rig.transformCount())
151  {
152  rewind(start);
153  }
154 
155  void rewind(int start = -1)
156  {
157  myIndex = 0;
158  myEnd = 0;
159 
160  if (start < 0)
161  {
162  for(int i : myRig.roots())
163  myQueue[myEnd++] = i;
164  }
165  else
166  myQueue[myEnd++] = start;
167  }
168 
169  inline void advance()
170  {
171  const int i = myQueue[myIndex];
172 
173  // Queue the child transforms for processing.
174  for (int child = 0, n = myRig.childCount(i); child < n; ++child)
175  {
176  myQueue[myEnd++] = myRig.childIndex(i, child);
177  UT_ASSERT_P(myEnd <= myRig.transformCount());
178  }
179 
180  ++myIndex;
181  }
182 
183  inline bool atEnd() const
184  {
185  return myIndex == myEnd;
186  }
187 
188  /// Returns the transform index
189  inline int operator*() const { return myQueue[myIndex]; }
190 
191  /// Pre-increment operator
192  inline const_iterator& operator++() { advance(); return *this; }
193 
194  private:
195  const GU_AgentRig &myRig;
196  int myIndex;
197  int myEnd;
198  // We know our total number of xforms is bounded, so we
199  // can allocate potentially on the stack the full queue.
201  };
202 
203  /// Adds a list of channels to the rig. Agents can store a list of values
204  /// for these channels (e.g. for driving blendshapes), and these channels
205  /// can be sampled from any GU_AgentClip.
206  bool addChannels(const UT_StringArray &names,
207  const UT_Array<FloatType> &default_values,
208  const UT_IntArray &transforms,
209  UT_StringArray &errors);
210  /// Adds or replaces a channel in the rig.
211  void addChannel(const UT_StringHolder &name, FloatType default_value,
212  exint xform_idx);
213 
214  /// Returns the number of channels.
215  exint channelCount() const { return myChannels.size(); }
216  /// Returns the name of the specified channel.
217  const UT_StringHolder &channelName(exint i) const { return myChannels[i]; }
218  /// Returns the default value of the specified channel.
219  FloatType channelDefaultValue(exint i) const;
220  /// Returns the transform index associated with the channel, or -1.
221  exint channelTransform(exint i) const;
222 
223  /// Returns the index of the channel with the specified name, or -1 if it
224  /// does not exist.
225  exint findChannel(const UT_StringRef &name) const;
226 
227 private:
228  UT_StringHolder myName;
229  bool myIsFile;
230 
231  // We build a symbol table sharing the string in the myTransforms array
232  UT_StringArray myTransforms; // One per transform
233  NameMapType myTransformsMap; // Map from names to indices
234 
235  UT_IntArray myParents; // Indices to parent transform
236  UT_IntArray myChildStarts; // One per transform, indices into
237  // myChildren for where the children
238  // for the i'th transform starts.
239  UT_IntArray myChildren; // Child pointers
240  UT_IntArray myRoots; // Root transform(s) of the rig.
241 
242  UT_Array<Xform> myRestLocalXforms; // Rest pose in local space.
243  UT_Array<Matrix4> myRestWorldXforms; // Cached world space rest pose.
244 
245  UT_StringArray myChannels;
246  NameMapType myChannelMap;
247  UT_Array<FloatType> myChannelDefaultValues;
248  UT_IntArray myChannelTransforms;
249 
250  exint myUniqueId;
251 };
252 
253 ///////////////////////////////////////////////////////////////////////////////
254 //
255 // Implementation
256 //
257 
258 inline exint
260 {
261  NameMapConstIter it = myTransformsMap.find(name);
262  if (it == myTransformsMap.end())
263  return -1;
264  return it->second;
265 }
266 
267 inline exint
269 {
270  auto it = myChannelMap.find(name);
271  return it != myChannelMap.end() ? it->second : -1;
272 }
273 
276 {
277  return myChannelDefaultValues[i];
278 }
279 
280 inline exint
282 {
283  return myChannelTransforms[i];
284 }
285 
286 #endif
exint findTransform(const UT_StringRef &name) const
Find a transform by name. Returns -1 for an invalid name.
Definition: GU_AgentRig.h:259
NameMapType::const_iterator NameMapConstIter
Definition: GU_AgentRig.h:42
const_iterator & operator++()
Pre-increment operator.
Definition: GU_AgentRig.h:192
void rewind(int start=-1)
Definition: GU_AgentRig.h:155
GT_API const UT_StringHolder filename
GLuint start
Definition: glcorearb.h:475
const Xform & restLocalTransform(exint i) const
Returns the rest local transform for the specified joint.
Definition: GU_AgentRig.h:128
exint childCount(exint i) const
Return the number of children for the given transform.
Definition: GU_AgentRig.h:110
int64 exint
Definition: SYS_Types.h:125
const UT_StringHolder & transformName(exint i) const
Return the name of the given transform.
Definition: GU_AgentRig.h:104
FloatType channelDefaultValue(exint i) const
Returns the default value of the specified channel.
Definition: GU_AgentRig.h:275
JSON reader class which handles parsing of JSON or bJSON files.
Definition: UT_JSONParser.h:87
exint channelTransform(exint i) const
Returns the transform index associated with the channel, or -1.
Definition: GU_AgentRig.h:281
exint getUniqueId() const
Unique ID of the rig.
Definition: GU_AgentRig.h:78
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:37
exint childIndex(exint transform, exint child) const
Return the Nth child for the given transform.
Definition: GU_AgentRig.h:115
A reference counter base class for use with UT_IntrusivePtr.
float fpreal32
Definition: SYS_Types.h:200
NameMapType::iterator NameMapIter
Definition: GU_AgentRig.h:43
Parent::iterator iterator
Definition: UT_StringMap.h:52
exint findChannel(const UT_StringRef &name) const
Definition: GU_AgentRig.h:268
exint parentIndex(exint i) const
Return the parent of the given transform (or -1 for the root)
Definition: GU_AgentRig.h:107
GLdouble n
Definition: glcorearb.h:2008
A rig for the agent primitive.
Definition: GU_AgentRig.h:38
exint channelCount() const
Returns the number of channels.
Definition: GU_AgentRig.h:215
const UT_IntArray & roots() const
Return the root transform(s) of the rig.
Definition: GU_AgentRig.h:121
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:155
A factored transform geared for animation blending.
Definition: GU_AgentXform.h:20
Wrapper around hboost::intrusive_ptr.
long long int64
Definition: SYS_Types.h:116
#define GU_API
Definition: GU_API.h:14
GLuint const GLchar * name
Definition: glcorearb.h:786
UT_Matrix4T< FloatType > Matrix4
Definition: GU_AgentRig.h:46
GA_API const UT_StringHolder transform
Parent::const_iterator const_iterator
Definition: UT_StringMap.h:51
void setName(const UT_StringHolder &name)
Definition: GU_AgentRig.h:84
int operator*() const
Returns the transform index.
Definition: GU_AgentRig.h:189
GU_AgentXformT< FloatType > Xform
Definition: GU_AgentRig.h:45
UT_StringMap< exint > NameMapType
Definition: GU_AgentRig.h:41
UT_IntrusivePtr< GU_AgentRig > GU_AgentRigPtr
Definition: GU_AgentRig.h:32
bool isFile() const
Return whether the rig was loaded from disk.
Definition: GU_AgentRig.h:89
UT_IntrusivePtr< const GU_AgentRig > GU_AgentRigConstPtr
Definition: GU_AgentRig.h:34
const_iterator(const GU_AgentRig &rig, int start=-1)
Definition: GU_AgentRig.h:149
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
const UT_StringHolder & name() const
Definition: GU_AgentRig.h:82
const UT_StringHolder & channelName(exint i) const
Returns the name of the specified channel.
Definition: GU_AgentRig.h:217
exint transformCount() const
Return number of transforms.
Definition: GU_AgentRig.h:101
fpreal32 FloatType
Definition: GU_AgentRig.h:44
const Matrix4 & restWorldTransform(exint i) const
Returns the rest world transform for the specified joint.
Definition: GU_AgentRig.h:131
GLenum src
Definition: glcorearb.h:1793