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,
191  const UT_Array<GU_AgentShapeDeformerConstPtr> &deformers,
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  UT_StringArray *errors = nullptr);
210 
211  int64 getMemoryUsage(bool inclusive) const;
212 
213  /// Return a unique name for the layer. This is the filename if the layer
214  /// was loaded from disk.
215  const NameType &uniqueName() const { return myUniqueName; }
216 
217  /// Name accessor
218  /// @{
219  const NameType &name() const { return myLayerName; }
220  void setName(const NameType &name) { myLayerName = name; }
221  /// @}
222 
223  /// Return whether the layer was loaded from disk.
224  bool isFile() const { return myIsFile; }
225  /// Clear the flag marking that the layer references a file on disk.
226  void clearIsFile();
227 
228  /// Return the rig associated with the layer.
229  const GU_AgentRig &rig() const { return *myRig; }
230 
231  /// Return the underlying geometry.
232  GU_ConstDetailHandle detail() const { return myShapeLib->detail(); }
233 
234  /// Return the shape library for the layer.
235  const GU_AgentShapeLib &shapeLib() const { return *myShapeLib; }
236 
237  /// @{
238  /// Shape count
239  exint entries() const
240  { return myShapes.entries(); }
242  { return myStaticShapes.entries(); }
244  { return myDeformingShapes.entries(); }
245  /// @}
246 
247  /// Return the number of shapes bound to a specific transform.
248  exint numBoundShapes(exint xform_idx) const
249  {
250  return myTransformStarts(xform_idx + 1) - myTransformStarts(xform_idx);
251  }
252 
253  bool save(UT_JSONWriter &w) const;
254  /// Load the layer from a JSON file.
255  bool load(UT_JSONParser &p);
256  /// @{
257  /// Parse the JSON file into an intermediate format, which can be used to
258  /// load the layer at a later time.
259  static bool load(UT_JSONParser &p, LayerData &data);
260  bool load(const LayerData &data, UT_StringArray &errors);
261  /// @}
262 
263  /// Clear the layer
264  void clear();
265 
266  /// Get binding information for the given shape.
267  const ShapeBinding &shape(exint i) const { return myShapes(i); }
268 
269  /// Get binding information for the ith shape bound to the given transform.
270  /// @see numBoundShapes
272  { return myShapes(myTransformStarts(transform) + i); }
273 
274  /// Return the indices of the static shapes in the layer.
275  /// @see shape
276  const UT_IntArray &getStatic() const { return myStaticShapes; }
277 
278  /// Return the indices of the deforming shapes in the layer.
279  /// @see shape
280  const UT_IntArray &getDeforming() const { return myDeformingShapes; }
281 
282  /// Get the geometry for the given shape binding.
283  GU_ConstDetailHandle shapeGeometry(const ShapeBinding &shape_binding) const;
284  /// Get the geometry for the given shape index.
286  { return shapeGeometry(shape(i)); }
287 
288  /// Update the shape bindings when the shape library gets modified.
289  void updateShapes();
290 
291  /// Enlarge bounding box based on the shapes inside along with the
292  /// transform array.
293  void enlargeBounds(UT_BoundingBox &box,
294  const GU_Agent &agent,
295  const UT_Array<UT_Matrix4F> &xforms) const;
296 
297  /// Expand the given velocity range using the v attributes in the shapes.
298  bool expandVelocityRange(UT_Vector3& vmin, UT_Vector3& vmax) const;
299 
300  /// Unpack geometry into a detail
301  /// NOTE: This transforms the unpacked geometry by the agent's xform.
302  bool unpackToDetail(
303  GU_Detail &dest,
304  const GU_PrimPacked *prim,
305  const GU_Agent &agent,
306  const GU_AgentRig &rig,
307  const UT_Array<UT_Matrix4F> &xforms,
308  STY_StylerGroup *prim_styler_group,
309  const STY_Styler *parent_styler,
310  const UT_Matrix4D *transform) const;
311 
312  /// @{
313  /// Unpack a specific shape into a detail.
314  /// NOTE: This does not transform the geometry by the agent's xform.
315  /// The apply_joint_xform flag controls whether the transform from the
316  /// shape binding's joint is applied.
317  bool unpackShapeToDetail(
318  GU_Detail &dest,
319  const ShapeBinding &binding,
320  const GU_Agent &agent,
321  const GU_AgentRig &rig,
322  const UT_Array<UT_Matrix4F> &xforms,
323  bool apply_joint_xform = true) const;
325  GU_Detail &dest,
326  exint shape_i,
327  const GU_Agent &agent,
328  const GU_AgentRig &rig,
329  const UT_Array<UT_Matrix4F> &xforms) const
330  {
331  return myShapes.isValidIndex(shape_i)
332  ? unpackShapeToDetail(dest, shape(shape_i), agent, rig, xforms)
333  : false;
334  }
335  /// @}
336 
337  /// @{
338  /// Iterators
339  const_iterator begin() const { return myShapes.begin(); }
340  const_iterator end() const { return myShapes.end(); }
341  /// @}
342 
343  /// Register a new shape deformer.
344  static void registerDeformer(const GU_AgentShapeDeformerConstPtr &deformer);
345 
346  /// Return the deformer with the given name, or nullptr.
347  static GU_AgentShapeDeformerConstPtr findDeformer(const UT_StringRef &name);
348 
349  /// Return a list of the registered deformers.
350  static UT_Array<GU_AgentShapeDeformerConstPtr> registeredDeformers();
351 
352  /// Called by GU_Agent during startup to register default deformers and
353  /// load any custom deformers.
354  static void installDeformers();
355  static bool runDSO(const char* lib_path);
356 
357  /// Return the deformer for the specified skinning method. Defaults to
358  /// normal linear skinning.
360  getLinearSkinDeformer(GU_AgentLinearSkinDeformer::Method method =
362 
363  /// Returns the blendshape deformer (no skinning is performed).
364  static GU_AgentShapeDeformerConstPtr getBlendShapeDeformer();
365 
366  /// Returns the blendshape deformer that is composed with the specified
367  /// skinning method.
368  static GU_AgentShapeDeformerConstPtr getBlendShapeAndSkinDeformer(
369  GU_AgentLinearSkinDeformer::Method skinning_method =
371 
372  /// Returns the ML skin deformer.
373  static GU_AgentShapeDeformerConstPtr getMLSkinDeformer();
374 
375  /// Convenience method to return the dual quaternion skinning deformer.
377  {
378  return getLinearSkinDeformer(
380  }
381 
382  /// Convenience method to return the blended dual quaternion skinning
383  /// deformer.
385  {
386  return getLinearSkinDeformer(
388  }
389 
390  /// Returns the appropriate built-in agent shape deformer based on the
391  /// presence of akinning and/or blendshapes.
392  /// Returns nullptr if skinning and blendshapes are both disabled.
394  getStandardDeformer(
396  bool has_blendshapes);
397 
398 private:
399  /// Add a shape from the shape library to the layer.
400  /// @see sortShapeList
401  bool addShape(const NameType &name, exint transform_id,
402  const GU_AgentShapeDeformerConstPtr &deformer,
403  const UT_Vector3F &bounds_scale);
404 
405  /// Sort myShapes and rebuild the static/deforming shape lists.
406  void sortShapeList(UT_StringArray *warnings);
407 
408  NameType myUniqueName;
409  NameType myLayerName;
410  bool myIsFile;
411  GU_AgentRigConstPtr myRig;
412  GU_AgentShapeLibConstPtr myShapeLib;
413 
414  /// List of the shape bindings in the layer, ordered by transform.
415  ShapeArray myShapes;
416  /// Indices of the static shapes in myShapes.
417  UT_IntArray myStaticShapes;
418  /// Indices of the deforming shapes in myShapes.
419  UT_IntArray myDeformingShapes;
420  /// For each transform, stores the index into myShapes for where the shape
421  /// bindings attached to that transform begin.
422  UT_IntArray myTransformStarts;
423 
424  static GU_AgentShapeDeformerConstPtr theLinearSkinDeformer;
425 };
426 
427 extern "C" {
428  /// Entry point for registering custom deformers.
430 };
431 
432 #endif
#define SYSmax(a, b)
Definition: SYS_Math.h:1952
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
that also have some descendant prim *whose name begins with which in turn has a child named baz where *the predicate and *a name There is also one special expression _ which means *the weaker expression when composing expressions together See with
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:39
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.
OutGridT const XformOp bool bool
#define GA_INVALID_OFFSET
Definition: GA_Types.h:694
std::optional< T > UT_Optional
Definition: UT_Optional.h:26
#define SYS_DEPRECATED_REPLACE(__V__, __R__)
GA_Size GA_Offset
Definition: GA_Types.h:653
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:1032
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
const UT_IntArray & getStatic() const
const UT_BoundingBoxF & bounds() const
UT_Array< ShapeBinding > ShapeArray
Definition: format.h:1821
GA_Offset offset() const
GLenum src
Definition: glcorearb.h:1793