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