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