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"
17 #include "GU_AgentShapeLib.h"
18 #include "GU_PackedImpl.h"
19 #include <UT/UT_BoundingBox.h>
20 #include <UT/UT_Map.h>
21 #include <UT/UT_VectorTypes.h>
22 
26 
27 /// A packed agent
28 ///
29 /// The agent is composed of multiple named layers. Each layer consists of
30 /// zero or more shapes.
31 ///
32 /// All agents must have a default layer. This is the layer used when a
33 /// specific layer isn't found. Example layers might be:
34 /// - "default": The default layer
35 /// - "low": Low resolution representation
36 /// - "medium": Medium resolution
37 /// - "high": High resolution
38 /// - "collision": Used for collision detection
39 ///
40 /// The packed agent conforms to the GU_PackedImpl API, but also provides
41 /// access to the layers/shapes.
42 class GU_API GU_AgentLayer : public UT_IntrusiveRefCounter<GU_AgentLayer>
43 {
44 public:
47 
48  /// Used to store the result of parsing a shape binding from a JSON file.
50  {
55  };
56 
57  /// Used to store the result of parsing a layer from a JSON file.
58  struct LayerData
59  {
63  };
64 
66  {
67  public:
69  : myShapeName() // Definition of shape name
70  , myShapeId(-1) // Unique id corresponding to shape
71  , myOffset(GA_INVALID_OFFSET) // Offset in shape library's detail.
72  , myTransformId(-1) // Root transform
73  , myDeformer(nullptr)
74  , myBoundsScale(1.0) // BBox scale for the shape
75  , myShapePtr(NULL)
76  {
77  myBounds.makeInvalid();
78  }
79 
81  const NameType &name,
82  const ShapePtr &shape,
84  int transform_id,
85  bool deforming,
86  const UT_BoundingBoxF &bounds,
87  fpreal bounds_scale = 1.0)
88  : ShapeBinding(lib, name, shape, offset, transform_id,
89  deforming ? theLinearSkinDeformer : nullptr,
90  bounds, bounds_scale)
91  {
92  }
93 
95  const NameType &name,
96  const ShapePtr &shape,
98  int transform_id,
99  const GU_AgentShapeDeformerConstPtr &deformer,
100  const UT_BoundingBoxF &bounds,
101  fpreal bounds_scale = 1.0)
102  : myShapeName(name)
103  , myShapeId(shape->uniqueId())
104  , myOffset(offset)
105  , myTransformId(transform_id)
106  , myBounds(bounds)
107  , myBoundsScale(bounds_scale)
108  , myShapePtr(shape)
109  , myDeformer(deformer)
110  {
111  }
112 
113  int64 getMemoryUsage(bool inclusive) const;
114 
115  GA_Offset offset() const { return myOffset; }
116  int transformId() const { return myTransformId; }
117  const UT_BoundingBoxF &bounds() const { return myBounds; }
118  fpreal boundsScale() const { return myBoundsScale; }
119  bool isDeforming() const { return myDeformer != nullptr; }
120  const GU_AgentShapeDeformerConstPtr deformer() const { return myDeformer; }
121 
122  bool save(UT_JSONWriter &w, const GU_AgentRig& rig) const;
123  static bool load(UT_JSONParser &p, ShapeBindingData &data);
124 
125  // Access to the underlying shape library
126  const NameType &shapeName() const { return myShapeName; }
127  int shapeId() const { return myShapeId; }
128  ShapePtr shape() const { return myShapePtr; }
129 
130  // Check if our shape is out-of-date
131  bool isDirty(const GU_AgentShapeLib &lib) const;
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  fpreal myBoundsScale;
142  };
145 
146  static GU_AgentLayerPtr addLayer(const char *unique_name,
147  const GU_AgentRigConstPtr &rig,
148  const GU_AgentShapeLibConstPtr &shapelib);
149  static GU_AgentLayerPtr addLayerFromFile(
150  const char *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 char *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: Optional scale for the bounding boxes.
176  bool construct(const UT_StringArray &shape_names,
177  const UT_IntArray &transforms,
179  const UT_FprealArray *bounds_scales = 0);
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 deforming: Whether each shape is static or deforming.
185  /// - @c bounds_scales: Optional scale for the bounding boxes.
186  bool construct(const UT_StringArray &shape_names,
187  const UT_IntArray &transforms,
188  const UT_Array<bool> &deforming,
189  const UT_FprealArray *bounds_scales = 0);
190 
191  /// Add the shape bindings from another layer.
192  bool copyShapeBindings(const GU_AgentLayer &source);
193 
194  int64 getMemoryUsage(bool inclusive) const;
195 
196  /// Return a unique name for the layer (since there may e.g. be many
197  /// different layer definitions named 'collision'). This is the filename if
198  /// the layer was loaded from disk.
199  const NameType &uniqueName() const { return myUniqueName; }
200 
201  /// Name accessor
202  /// @{
203  const NameType &name() const { return myLayerName; }
204  void setName(const NameType &name) { myLayerName = name; }
205  /// @}
206 
207  /// Return whether the layer was loaded from disk.
208  bool isFile() const { return myIsFile; }
209  /// Clear the flag marking that the layer references a file on disk.
210  void clearIsFile();
211 
212  /// Return the rig associated with the layer.
213  const GU_AgentRig &rig() const { return *myRig; }
214 
215  /// Return the underlying geometry.
216  GU_ConstDetailHandle detail() const { return myShapeLib->detail(); }
217 
218  /// Return the shape library for the layer.
219  const GU_AgentShapeLib &shapeLib() const { return *myShapeLib; }
220 
221  /// @{
222  /// Shape count
223  exint entries() const
224  { return myShapes.entries(); }
226  { return myStaticShapes.entries(); }
228  { return myDeformingShapes.entries(); }
229  /// @}
230 
231  /// Return the number of shapes bound to a specific transform.
232  exint numBoundShapes(exint xform_idx) const
233  {
234  return myTransformStarts(xform_idx + 1) - myTransformStarts(xform_idx);
235  }
236 
237  bool save(UT_JSONWriter &w) const;
238  /// Load the layer from a JSON file.
239  bool load(UT_JSONParser &p);
240  /// @{
241  /// Parse the JSON file into an intermediate format, which can be used to
242  /// load the layer at a later time.
243  static bool load(UT_JSONParser &p, LayerData &data);
244  bool load(const LayerData &data, UT_StringArray &errors);
245  /// @}
246 
247  /// Clear the layer
248  void clear();
249 
250  /// Get binding information for the given shape.
251  const ShapeBinding &shape(exint i) const { return myShapes(i); }
252 
253  /// Get binding information for the ith shape bound to the given transform.
254  /// @see numBoundShapes
256  { return myShapes(myTransformStarts(transform) + i); }
257 
258  /// Return the indices of the static shapes in the layer.
259  /// @see shape
260  const UT_IntArray &getStatic() const { return myStaticShapes; }
261 
262  /// Return the indices of the deforming shapes in the layer.
263  /// @see shape
264  const UT_IntArray &getDeforming() const { return myDeformingShapes; }
265 
266  /// Get the geometry for the given shape binding.
267  GU_ConstDetailHandle shapeGeometry(const ShapeBinding &shape_binding) const;
268  /// Get the geometry for the given shape index.
270  { return shapeGeometry(shape(i)); }
271 
272  /// Get deformer source for given shape binding if present. Only valid for
273  /// deforming shapes.
275  shapeDeformerSource(const ShapeBinding &shape) const;
276  /// Get deformer source for given shape index if present. Only valid for
277  /// deforming shapes.
279  shapeDeformerSource(exint i) const { return shapeDeformerSource(shape(i)); }
280 
281  /// Update the shape bindings when the shape library gets modified.
282  void updateShapes();
283 
284  /// Enlarge bounding box based on the shapes inside along with the
285  /// transform array.
286  void enlargeBounds(UT_BoundingBox &box,
287  const UT_Array<UT_Matrix4F> &xforms) const;
288 
289  /// Expand the given velocity range using the v attributes in the shapes.
290  bool expandVelocityRange(UT_Vector3& vmin, UT_Vector3& vmax) const;
291 
292  /// Unpack geometry into a detail
293  /// NOTE: This transforms the unpacked geometry by the agent's xform.
294  bool unpackToDetail(
295  GU_Detail &dest,
296  const GU_PrimPacked *prim,
297  const GU_Agent &agent,
298  const GU_AgentRig &rig,
299  const UT_Array<UT_Matrix4F> &xforms,
300  STY_StylerGroup *prim_styler_group,
301  const STY_Styler *parent_styler,
302  const UT_Matrix4D *transform) const;
303 
304  /// @{
305  /// Unpack a specific shape into a detail.
306  /// NOTE: This does not transform the geometry by the agent's xform.
307  bool unpackShapeToDetail(
308  GU_Detail &dest,
309  const ShapeBinding &binding,
310  const GU_Agent &agent,
311  const GU_AgentRig &rig,
312  const UT_Array<UT_Matrix4F> &xforms) const;
314  GU_Detail &dest,
315  exint shape_i,
316  const GU_Agent &agent,
317  const GU_AgentRig &rig,
318  const UT_Array<UT_Matrix4F> &xforms) const
319  {
320  return myShapes.isValidIndex(shape_i)
321  ? unpackShapeToDetail(dest, shape(shape_i), agent, rig, xforms)
322  : false;
323  }
324  /// @}
325 
326  /// @{
327  /// Iterators
328  const_iterator begin() const { return myShapes.begin(); }
329  const_iterator end() const { return myShapes.end(); }
330  /// @}
331 
332  /// Register a new shape deformer.
333  static void registerDeformer(const GU_AgentShapeDeformerConstPtr &deformer);
334 
335  /// Return the deformer with the given name, or nullptr.
336  static GU_AgentShapeDeformerConstPtr findDeformer(const UT_StringRef &name);
337 
338  /// Return a list of the registered deformers.
339  static UT_Array<GU_AgentShapeDeformerConstPtr> registeredDeformers();
340 
341  /// Called by GU_Agent during startup to register default deformers and
342  /// load any custom deformers.
343  static void installDeformers();
344 
345  /// Return the default (linear skinning) deformer.
347  {
348  return theLinearSkinDeformer;
349  }
350 
351  /// Return the dual quaternion skinning deformer.
353  {
354  return theDualQuatSkinDeformer;
355  }
356 
357 private:
358  /// Add a shape from the shape library to the layer.
359  /// @see sortShapeList
360  bool addShape(const NameType &name, int transform_id,
361  const GU_AgentShapeDeformerConstPtr &deformer,
362  fpreal bounds_scale = 1.0);
363 
364  /// Sort myShapes and rebuild the static/deforming shape lists.
365  void sortShapeList();
366 
368  shapeDeformerSource(const ShapeBinding &shape,
369  const GU_ConstDetailHandle &packed_geo) const;
370 
371  NameType myUniqueName;
372  NameType myLayerName;
373  bool myIsFile;
374  GU_AgentRigConstPtr myRig;
375  GU_AgentShapeLibConstPtr myShapeLib;
376 
377  /// List of the shape bindings in the layer, ordered by transform.
378  ShapeArray myShapes;
379  /// Indices of the static shapes in myShapes.
380  UT_IntArray myStaticShapes;
381  /// Indices of the deforming shapes in myShapes.
382  UT_IntArray myDeformingShapes;
383  /// For each transform, stores the index into myShapes for where the shape
384  /// bindings attached to that transform begin.
385  UT_IntArray myTransformStarts;
386 
387  static GU_AgentShapeDeformerConstPtr theLinearSkinDeformer;
388  static GU_AgentShapeDeformerConstPtr theDualQuatSkinDeformer;
389 };
390 
391 extern "C" {
392  /// Entry point for registering custom deformers.
394 };
395 
396 #endif
UT_StringHolder NameType
Definition: GU_AgentLayer.h:45
GT_API const UT_StringHolder filename
exint deformingEntries() const
const NameType & uniqueName() const
png_infop int transforms
Definition: png.h:2591
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
const UT_IntArray & getDeforming() const
const GU_LinearSkinDeformerSource * shapeDeformerSource(exint i) const
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
3D Vector class.
A reference counter base class for use with UT_IntrusivePtr.
static GU_AgentShapeDeformerConstPtr getLinearSkinDeformer()
Return the default (linear skinning) deformer.
const_iterator end() const
const GU_AgentShapeDeformerConstPtr deformer() const
png_uint_32 i
Definition: png.h:2877
static GU_AgentShapeDeformerConstPtr getDualQuatSkinDeformer()
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:654
GA_Size GA_Offset
Definition: GA_Types.h:617
const NameType & shapeName() const
long long int64
Definition: SYS_Types.h:107
A rig for the agent primitive.
Definition: GU_AgentRig.h:34
UT_IntrusivePtr< const GU_AgentLayer > GU_AgentLayerConstPtr
Definition: GU_AgentLayer.h:25
const ShapeBinding & shape(exint i) const
Get binding information for the given shape.
const ShapeBinding & boundShape(exint transform, exint i) const
Class representing source data for GU_LinearSkinDeformer.
int64 exint
Definition: SYS_Types.h:116
Used to store the result of parsing a shape binding from a JSON file.
Definition: GU_AgentLayer.h:49
GLsizei GLsizei GLchar * source
Definition: glcorearb.h:802
GLintptr offset
Definition: glcorearb.h:664
Wrapper around hboost::intrusive_ptr.
GU_AgentShapeLib::ShapePtr ShapePtr
Definition: GU_AgentLayer.h:46
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:94
UT_Array< ShapeBindingData > myDeforming
Definition: GU_AgentLayer.h:62
#define GU_API
Definition: GU_API.h:12
GLboolean * data
Definition: glcorearb.h:130
UT_StringHolder myLayerName
Definition: GU_AgentLayer.h:60
GLuint const GLchar * name
Definition: glcorearb.h:785
GA_API const UT_StringHolder transform
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:80
Used to store the result of parsing a layer from a JSON file.
Definition: GU_AgentLayer.h:58
GU_ConstDetailHandle detail() const
Return the underlying geometry.
double fpreal
Definition: SYS_Types.h:270
UT_IntrusivePtr< GU_AgentLayer > GU_AgentLayerPtr
Definition: GU_AgentLayer.h:23
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:772
UT_Array< ShapeBindingData > myStatic
Definition: GU_AgentLayer.h:61
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:856
exint staticEntries() const
const UT_IntArray & getStatic() const
const UT_BoundingBoxF & bounds() const
UT_Array< ShapeBinding > ShapeArray
GA_Offset offset() const
GLenum src
Definition: glcorearb.h:1792