HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_AgentLayer.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_AgentLayer.h (GU Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GU_AgentLayer__
12 #define __GU_AgentLayer__
13 
14 #include "GU_API.h"
15 #include "GU_AgentRig.h"
16 #include "GU_AgentShapeDeformer.h"
18 #include "GU_AgentShapeLib.h"
19 #include "GU_PackedImpl.h"
20 #include <SYS/SYS_Deprecated.h>
21 #include <UT/UT_BoundingBox.h>
22 #include <UT/UT_Map.h>
23 #include <UT/UT_Optional.h>
24 #include <UT/UT_VectorTypes.h>
25 
29 
30 /// A packed agent
31 ///
32 /// The agent is composed of multiple named layers. Each layer consists of
33 /// zero or more shapes.
34 ///
35 /// All agents must have a default layer. This is the layer used when a
36 /// specific layer isn't found. Example layers might be:
37 /// - "default": The default layer
38 /// - "low": Low resolution representation
39 /// - "medium": Medium resolution
40 /// - "high": High resolution
41 /// - "collision": Used for collision detection
42 ///
43 /// The packed agent conforms to the GU_PackedImpl API, but also provides
44 /// access to the layers/shapes.
45 class GU_API GU_AgentLayer : public UT_IntrusiveRefCounter<GU_AgentLayer>
46 {
47 public:
50 
51  /// Used to store the result of parsing a shape binding from a JSON file.
53  {
58  };
59 
60  /// Used to store the result of parsing a layer from a JSON file.
61  struct LayerData
62  {
66  };
67 
69  {
70  public:
72  : myShapeName() // Definition of shape name
73  , myShapeId(-1) // Unique id corresponding to shape
74  , myOffset(GA_INVALID_OFFSET) // Offset in shape library's detail.
75  , myTransformId(INVALID_TRANSFORM_ID) // Transform that the shape is attached to.
76  , myDeformer(nullptr)
77  , myBoundsScale(1.0, 1.0, 1.0) // BBox scale for the shape
78  , myShapePtr(NULL)
79  {
80  myBounds.makeInvalid();
81  }
82 
84  const NameType &name,
85  const ShapePtr &shape,
87  int transform_id,
88  const GU_AgentShapeDeformerConstPtr &deformer,
89  const UT_BoundingBoxF &bounds,
90  const UT_Vector3F &bounds_scale)
91  : myShapeName(name)
92  , myShapeId(shape->uniqueId())
93  , myOffset(offset)
94  , myTransformId(SYSmax(transform_id, INVALID_TRANSFORM_ID))
95  , myBounds(bounds)
96  , myBoundsScale(bounds_scale)
97  , myShapePtr(shape)
98  , myDeformer(deformer)
99  {
100  }
101 
102  bool operator==(const ShapeBinding &) const;
103 
104  int64 getMemoryUsage(bool inclusive) const;
105 
106  GA_Offset offset() const { return myOffset; }
107 
108  int transformId() const { return myTransformId; }
109  /// The transform is optional, which is typically used for deforming
110  /// shapes. For static shapes, this means that they'll only be
111  /// transformed by the agent's overall transform.
112  bool isAttachedToTransform() const { return myTransformId >= 0; }
113 
114  const UT_BoundingBoxF &bounds() const { return myBounds; }
115  const UT_Vector3F &boundsScale() const { return myBoundsScale; }
116 
117  bool isDeforming() const { return myDeformer != nullptr; }
118  const GU_AgentShapeDeformerConstPtr &deformer() const { return myDeformer; }
119 
120  bool save(UT_JSONWriter &w, const GU_AgentRig& rig) const;
121  static bool load(UT_JSONParser &p, ShapeBindingData &data, int version);
122 
123  // Access to the underlying shape library
124  const NameType &shapeName() const { return myShapeName; }
125  int shapeId() const { return myShapeId; }
126  ShapePtr shape() const { return myShapePtr; }
127 
128  // Check if our shape is out-of-date
129  bool isDirty(const GU_AgentShapeLib &lib) const;
130 
131  static constexpr int INVALID_TRANSFORM_ID = -1;
132 
133  private:
134  ShapePtr myShapePtr;
135  NameType myShapeName;
136  int myShapeId;
137  GA_Offset myOffset;
138  int myTransformId;
139  UT_BoundingBoxF myBounds; // Cached bounds for the shape.
140  UT_Vector3F myBoundsScale;
142  };
145 
146  static GU_AgentLayerPtr addLayer(const UT_StringHolder &unique_name,
147  const GU_AgentRigConstPtr &rig,
148  const GU_AgentShapeLibConstPtr &shapelib);
149  static GU_AgentLayerPtr addLayerFromFile(
150  const UT_StringHolder &filename, const GU_AgentRigConstPtr &rig,
151  const GU_AgentShapeLibConstPtr &shapelib, UT_StringArray &errors);
152 
153  /// Create a clone of a layer, referencing the specified rig and shape
154  /// library. 'copy_external_ref' should be disabled if the new layer will
155  /// have its bindings changed.
156  static GU_AgentLayerPtr
157  addLayerCopy(const GU_AgentLayer &src, const GU_AgentRigConstPtr &rig,
158  const GU_AgentShapeLibConstPtr &shapelib,
159  bool copy_external_ref);
160 
161 private:
162  // Use the static addLayer() method to create new layers.
163  GU_AgentLayer(const UT_StringHolder &unique_name, bool is_file,
164  const GU_AgentRigConstPtr &rig,
165  const GU_AgentShapeLibConstPtr &shapelib);
166 
167 public:
168  ~GU_AgentLayer();
169 
170  /// Add shape bindings to a layer.
171  /// - @c shape_names: The shape name for each shape binding.
172  /// - @c transforms: The transform index for each shape binding.
173  /// - @c deformers: A GU_AgentShapeDeformer for each shape binding, or
174  /// nullptr for static shapes.
175  /// - @c bounds_scales: Scales for the bounding boxes.
176  bool construct(const UT_StringArray &shape_names,
177  const UT_Array<exint> &transforms,
179  const UT_Array<UT_Vector3F> &bounds_scales,
180  UT_StringArray *errors = nullptr);
181 
182  /// Add shape bindings to a layer.
183  /// - @c shape_names: The shape name for each shape binding.
184  /// - @c transforms: The transform index for each shape binding.
185  /// - @c deformers: A GU_AgentShapeDeformer for each shape binding, or
186  /// nullptr for static shapes.
187  /// - @c bounds_scales: Optional scale for the bounding boxes.
188  SYS_DEPRECATED_REPLACE(19.0, "construct() with non-uniform bounds scales")
189  bool construct(const UT_StringArray &shape_names,
190  const UT_IntArray &transforms,
192  const UT_FprealArray *bounds_scales = nullptr,
193  UT_StringArray *errors = nullptr);
194 
195  /// Add shape bindings to a layer.
196  /// - @c shape_names: The shape name for each shape binding.
197  /// - @c transforms: The transform index for each shape binding.
198  /// - @c deforming: Whether each shape is static or deforming.
199  /// - @c bounds_scales: Optional scale for the bounding boxes.
200  SYS_DEPRECATED_REPLACE(19.0, "construct() with non-uniform bounds scales")
201  bool construct(const UT_StringArray &shape_names,
202  const UT_IntArray &transforms,
203  const UT_Array<bool> &deforming,
204  const UT_FprealArray *bounds_scales = nullptr,
205  UT_StringArray *errors = nullptr);
206 
207  /// Add the shape bindings from another layer.
208  bool copyShapeBindings(const GU_AgentLayer &source);
209 
210  int64 getMemoryUsage(bool inclusive) const;
211 
212  /// Return a unique name for the layer. This is the filename if the layer
213  /// was loaded from disk.
214  const NameType &uniqueName() const { return myUniqueName; }
215 
216  /// Name accessor
217  /// @{
218  const NameType &name() const { return myLayerName; }
219  void setName(const NameType &name) { myLayerName = name; }
220  /// @}
221 
222  /// Return whether the layer was loaded from disk.
223  bool isFile() const { return myIsFile; }
224  /// Clear the flag marking that the layer references a file on disk.
225  void clearIsFile();
226 
227  /// Return the rig associated with the layer.
228  const GU_AgentRig &rig() const { return *myRig; }
229 
230  /// Return the underlying geometry.
231  GU_ConstDetailHandle detail() const { return myShapeLib->detail(); }
232 
233  /// Return the shape library for the layer.
234  const GU_AgentShapeLib &shapeLib() const { return *myShapeLib; }
235 
236  /// @{
237  /// Shape count
238  exint entries() const
239  { return myShapes.entries(); }
241  { return myStaticShapes.entries(); }
243  { return myDeformingShapes.entries(); }
244  /// @}
245 
246  /// Return the number of shapes bound to a specific transform.
247  exint numBoundShapes(exint xform_idx) const
248  {
249  return myTransformStarts(xform_idx + 1) - myTransformStarts(xform_idx);
250  }
251 
252  bool save(UT_JSONWriter &w) const;
253  /// Load the layer from a JSON file.
254  bool load(UT_JSONParser &p);
255  /// @{
256  /// Parse the JSON file into an intermediate format, which can be used to
257  /// load the layer at a later time.
258  static bool load(UT_JSONParser &p, LayerData &data);
259  bool load(const LayerData &data, UT_StringArray &errors);
260  /// @}
261 
262  /// Clear the layer
263  void clear();
264 
265  /// Get binding information for the given shape.
266  const ShapeBinding &shape(exint i) const { return myShapes(i); }
267 
268  /// Get binding information for the ith shape bound to the given transform.
269  /// @see numBoundShapes
271  { return myShapes(myTransformStarts(transform) + i); }
272 
273  /// Return the indices of the static shapes in the layer.
274  /// @see shape
275  const UT_IntArray &getStatic() const { return myStaticShapes; }
276 
277  /// Return the indices of the deforming shapes in the layer.
278  /// @see shape
279  const UT_IntArray &getDeforming() const { return myDeformingShapes; }
280 
281  /// Get the geometry for the given shape binding.
282  GU_ConstDetailHandle shapeGeometry(const ShapeBinding &shape_binding) const;
283  /// Get the geometry for the given shape index.
285  { return shapeGeometry(shape(i)); }
286 
287  /// Update the shape bindings when the shape library gets modified.
288  void updateShapes();
289 
290  /// Enlarge bounding box based on the shapes inside along with the
291  /// transform array.
292  void enlargeBounds(UT_BoundingBox &box,
293  const GU_Agent &agent,
294  const UT_Array<UT_Matrix4F> &xforms) const;
295 
296  /// Expand the given velocity range using the v attributes in the shapes.
297  bool expandVelocityRange(UT_Vector3& vmin, UT_Vector3& vmax) const;
298 
299  /// Unpack geometry into a detail
300  /// NOTE: This transforms the unpacked geometry by the agent's xform.
301  bool unpackToDetail(
302  GU_Detail &dest,
303  const GU_PrimPacked *prim,
304  const GU_Agent &agent,
305  const GU_AgentRig &rig,
306  const UT_Array<UT_Matrix4F> &xforms,
307  STY_StylerGroup *prim_styler_group,
308  const STY_Styler *parent_styler,
309  const UT_Matrix4D *transform) const;
310 
311  /// @{
312  /// Unpack a specific shape into a detail.
313  /// NOTE: This does not transform the geometry by the agent's xform.
314  /// The apply_joint_xform flag controls whether the transform from the
315  /// shape binding's joint is applied.
316  bool unpackShapeToDetail(
317  GU_Detail &dest,
318  const ShapeBinding &binding,
319  const GU_Agent &agent,
320  const GU_AgentRig &rig,
321  const UT_Array<UT_Matrix4F> &xforms,
322  bool apply_joint_xform = true) const;
324  GU_Detail &dest,
325  exint shape_i,
326  const GU_Agent &agent,
327  const GU_AgentRig &rig,
328  const UT_Array<UT_Matrix4F> &xforms) const
329  {
330  return myShapes.isValidIndex(shape_i)
331  ? unpackShapeToDetail(dest, shape(shape_i), agent, rig, xforms)
332  : false;
333  }
334  /// @}
335 
336  /// @{
337  /// Iterators
338  const_iterator begin() const { return myShapes.begin(); }
339  const_iterator end() const { return myShapes.end(); }
340  /// @}
341 
342  /// Register a new shape deformer.
343  static void registerDeformer(const GU_AgentShapeDeformerConstPtr &deformer);
344 
345  /// Return the deformer with the given name, or nullptr.
346  static GU_AgentShapeDeformerConstPtr findDeformer(const UT_StringRef &name);
347 
348  /// Return a list of the registered deformers.
349  static UT_Array<GU_AgentShapeDeformerConstPtr> registeredDeformers();
350 
351  /// Called by GU_Agent during startup to register default deformers and
352  /// load any custom deformers.
353  static void installDeformers();
354 
355  /// Return the deformer for the specified skinning method. Defaults to
356  /// normal linear skinning.
358  getLinearSkinDeformer(GU_AgentLinearSkinDeformer::Method method =
360 
361  /// Returns the blendshape deformer (no skinning is performed).
362  static GU_AgentShapeDeformerConstPtr getBlendShapeDeformer();
363 
364  /// Returns the blendshape deformer that is composed with the specified
365  /// skinning method.
366  static GU_AgentShapeDeformerConstPtr getBlendShapeAndSkinDeformer(
367  GU_AgentLinearSkinDeformer::Method skinning_method =
369 
370  /// Convenience method to return the dual quaternion skinning deformer.
372  {
373  return getLinearSkinDeformer(
375  }
376 
377  /// Convenience method to return the blended dual quaternion skinning
378  /// deformer.
380  {
381  return getLinearSkinDeformer(
383  }
384 
385  /// Returns the appropriate built-in agent shape deformer based on the
386  /// presence of akinning and/or blendshapes.
387  /// Returns nullptr if skinning and blendshapes are both disabled.
389  getStandardDeformer(
391  bool has_blendshapes);
392 
393 private:
394  /// Add a shape from the shape library to the layer.
395  /// @see sortShapeList
396  bool addShape(const NameType &name, exint transform_id,
397  const GU_AgentShapeDeformerConstPtr &deformer,
398  const UT_Vector3F &bounds_scale);
399 
400  /// Sort myShapes and rebuild the static/deforming shape lists.
401  void sortShapeList(UT_StringArray *warnings);
402 
403  NameType myUniqueName;
404  NameType myLayerName;
405  bool myIsFile;
406  GU_AgentRigConstPtr myRig;
407  GU_AgentShapeLibConstPtr myShapeLib;
408 
409  /// List of the shape bindings in the layer, ordered by transform.
410  ShapeArray myShapes;
411  /// Indices of the static shapes in myShapes.
412  UT_IntArray myStaticShapes;
413  /// Indices of the deforming shapes in myShapes.
414  UT_IntArray myDeformingShapes;
415  /// For each transform, stores the index into myShapes for where the shape
416  /// bindings attached to that transform begin.
417  UT_IntArray myTransformStarts;
418 
419  static GU_AgentShapeDeformerConstPtr theLinearSkinDeformer;
420 };
421 
422 extern "C" {
423  /// Entry point for registering custom deformers.
425 };
426 
427 #endif
#define SYSmax(a, b)
Definition: SYS_Math.h:1538
UT_StringHolder NameType
Definition: GU_AgentLayer.h:48
GT_API const UT_StringHolder filename
exint deformingEntries() const
ShapeBinding(const GU_AgentShapeLib &lib, const NameType &name, const ShapePtr &shape, GA_Offset offset, int transform_id, const GU_AgentShapeDeformerConstPtr &deformer, const UT_BoundingBoxF &bounds, const UT_Vector3F &bounds_scale)
Definition: GU_AgentLayer.h:83
bool unpackShapeToDetail(GU_Detail &dest, exint shape_i, const GU_Agent &agent, const GU_AgentRig &rig, const UT_Array< UT_Matrix4F > &xforms) const
#define SYS_VISIBILITY_EXPORT
exint entries() const
ShapeArray::const_iterator const_iterator
SIM_API const UT_StringHolder agent
const_iterator begin() const
bool isAttachedToTransform() const
const UT_IntArray & getDeforming() const
int64 exint
Definition: SYS_Types.h:125
JSON reader class which handles parsing of JSON or bJSON files.
Definition: UT_JSONParser.h:87
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:37
A reference counter base class for use with UT_IntrusivePtr.
const_iterator end() const
static GU_AgentShapeDeformerConstPtr getDualQuatSkinDeformer()
Convenience method to return the dual quaternion skinning deformer.
exint numBoundShapes(exint xform_idx) const
Return the number of shapes bound to a specific transform.
#define GA_INVALID_OFFSET
Definition: GA_Types.h:678
std::optional< T > UT_Optional
Definition: UT_Optional.h:26
#define SYS_DEPRECATED_REPLACE(__V__, __R__)
GA_Size GA_Offset
Definition: GA_Types.h:641
static GU_AgentShapeDeformerConstPtr getDualQuatBlendSkinDeformer()
const NameType & shapeName() const
bool operator==(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:137
A rig for the agent primitive.
Definition: GU_AgentRig.h:38
UT_IntrusivePtr< const GU_AgentLayer > GU_AgentLayerConstPtr
Definition: GU_AgentLayer.h:28
GLintptr offset
Definition: glcorearb.h:665
const ShapeBinding & shape(exint i) const
Get binding information for the given shape.
const GU_AgentShapeDeformerConstPtr & deformer() const
const ShapeBinding & boundShape(exint transform, exint i) const
Used to store the result of parsing a shape binding from a JSON file.
Definition: GU_AgentLayer.h:52
GLsizei GLsizei GLchar * source
Definition: glcorearb.h:803
Wrapper around hboost::intrusive_ptr.
long long int64
Definition: SYS_Types.h:116
GU_AgentShapeLib::ShapePtr ShapePtr
Definition: GU_AgentLayer.h:49
UT_Array< ShapeBindingData > myDeforming
Definition: GU_AgentLayer.h:65
#define GU_API
Definition: GU_API.h:14
GLuint const GLchar * name
Definition: glcorearb.h:786
UT_StringHolder myLayerName
Definition: GU_AgentLayer.h:63
GA_API const UT_StringHolder transform
bool isFile() const
Return whether the layer was loaded from disk.
GT_API const UT_StringHolder version
Used to store the result of parsing a layer from a JSON file.
Definition: GU_AgentLayer.h:61
GU_ConstDetailHandle detail() const
Return the underlying geometry.
UT_IntrusivePtr< GU_AgentLayer > GU_AgentLayerPtr
Definition: GU_AgentLayer.h:26
void setName(const NameType &name)
SYS_VISIBILITY_EXPORT void GUregisterAgentShapeDeformer(void *)
Entry point for registering custom deformers.
GU_ConstDetailHandle shapeGeometry(exint i) const
Get the geometry for the given shape index.
const GU_AgentShapeLib & shapeLib() const
Return the shape library for the layer.
const GU_AgentRig & rig() const
Return the rig associated with the layer.
const NameType & name() const
base_iterator< const ShapeBinding, true > const_iterator
Definition: UT_Array.h:979
UT_Array< ShapeBindingData > myStatic
Definition: GU_AgentLayer.h:64
const UT_Vector3F & boundsScale() const
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
exint staticEntries() const
#define const
Definition: zconf.h:214
const UT_IntArray & getStatic() const
const UT_BoundingBoxF & bounds() const
UT_Array< ShapeBinding > ShapeArray
Definition: format.h:895
GA_Offset offset() const
GLenum src
Definition: glcorearb.h:1793