HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SIM_ConstraintNetworkIterator.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 
7 #ifndef __SIM_ConstraintNetworkIterator_h__
8 #define __SIM_ConstraintNetworkIterator_h__
9 
10 #include "SIM_API.h"
11 
12 #include "SIM_DataFilter.h"
13 #include "SIM_OptionsUser.h"
14 
15 #include <GA/GA_AttributeRef.h>
16 #include <GA/GA_Handle.h>
17 #include <GU/GU_DetailHandle.h>
18 #include <UT/UT_NonCopyable.h>
19 #include <UT/UT_StringMap.h>
20 #include <UT/UT_VectorTypes.h>
21 
22 class GA_Primitive;
23 class GA_PrimitiveGroup;
24 class GU_Detail;
26 class SIM_Data;
27 class SIM_Geometry;
29 class SIM_GeometryCopy;
30 class SIM_Object;
31 class SIM_Time;
32 
33 namespace SIM_ConstraintNetwork
34 {
35  /// The type of a constraint (linear, angular, or both).
36  enum class ConstraintType
37  {
38  Position,
39  Rotation,
40  All
41  };
42 
43  /// The type of anchor specfied by 'anchor_type' attribute. Defaults to
44  /// point.
45  enum class AnchorType
46  {
47  Point,
48  Vertex,
49  Agent
50  };
51 
52  /// How the position of the anchor is interpreted.
53  enum class PositionType
54  {
55  WorldSpace,
59  };
60 
61  /// Creates the 'force' and 'distance' primitive attributes.
64  /// Creates the 'torque' and 'angle' primitive attributes.
67 
68  /// Implements filtering of the constraint types that are recognized by the
69  /// caller, as well as caching / reading those constraint's parameter
70  /// values.
71  /// See @ref GenericConstraintAccessor for the default implementation.
73  {
74  public:
75  virtual ~ConstraintAccessor() {}
76 
77  /// Initialize with the constraint network's GU_Detail, and the number
78  /// of constraint types referenced by the geometry (from the
79  /// 'constraint_name' primitive attribute).
80  virtual void init(const GU_Detail *gdp, exint num_constraint_types) = 0;
81 
82  /// Returns whether the constraint type should be included when
83  /// iterating over the constraint network, and performs any necessary
84  /// caching with the constraint data and its index.
85  virtual bool acceptConstraint(const SIM_Data &constraint_data,
86  exint idx) = 0;
87  };
88 
89  /// Implements the mapping of anchors to objects recognized by the solver,
90  /// as well as evaluating anchor attributes (position, orientation, etc).
91  /// See @ref GenericAnchorAccessor for the default implementation.
93  {
94  public:
95  virtual ~AnchorAccessor() {}
96 
97  /// Initialize with the constraint network's GU_Detail and transform.
98  virtual bool init(
99  const GU_Detail &gdp, const UT_Matrix4D &xform,
100  const SIM_Data &container, const SIM_Data &data_root,
101  const SIM_Time &t) = 0;
102  };
103 
105  {
106  public:
107  /// @param container A SIM_Relationship or SIM_Object that contains the
108  /// constraint network as subdata.
109  /// @param data_root Parent of the SIM_ConRel subdata.
110  const_iterator(const SIM_Data &container, const SIM_Data &data_root,
111  const SIM_Geometry *geo, const SIM_Time &t,
112  ConstraintAccessor &constraint_accessor,
113  AnchorAccessor &anchor_accessor);
114 
115  const_iterator(const SIM_Data &container, const SIM_Data &data_root,
116  const SIM_Geometry *geo, const GU_Detail *gdp,
117  const GA_PrimitiveGroup *broken_group, const SIM_Time &t,
118  ConstraintAccessor &constraint_accessor,
119  AnchorAccessor &anchor_accessor);
120 
121  void rewind();
122  bool atEnd() const;
123  void advance();
124 
125  /// The constraint network geometry.
126  const GU_Detail &getGdp() const { return *myGdp; }
127  /// The number of valid constraints that have been seen so far.
128  exint getConstraintIndex() const { return myConstraintIndex; }
129  /// The primitive index.
130  GA_Index getPrimIndex() const;
131  /// The primitive offset.
132  GA_Offset getPrimOffset() const { return myPrimOffset; }
133 
134  /// Returns the index of the current constraint data type.
135  exint getConstraintDataIndex() const;
136 
137  /// Returns whether the constraint affects position / rotation / all.
138  ConstraintType getConstraintType() const;
139 
140  /// The point offset for this anchor in the constraint network geometry.
141  GA_Offset getPointOffset(bool anchor1) const;
142 
143  /// The point number for this anchor in the constraint network geometry.
144  GA_Index getPointNumber(bool anchor1) const;
145 
146  private:
147  void init(
148  const SIM_Data &container, const SIM_Geometry &geo,
149  const GU_Detail &gdp, const SIM_Time &t,
150  ConstraintAccessor &constraint_accessor,
151  AnchorAccessor &anchor_accessor);
152 
153  void skipInvalid();
154 
155  /// Returns false if nothing matched the filter.
156  bool buildConstraintDataCache(
157  const GU_Detail &gdp, ConstraintAccessor &constraint_accessor);
158  void buildConstraintTypeCache();
159 
160  const SIM_Data &myRootData;
161 
163  const GU_Detail *myGdp;
164 
165  GA_Offset myPrimOffset;
166  exint myConstraintDataIndex;
167  GA_Iterator myPrimIterator;
168 
169  /// Cached offsets for the primitive's two points.
170  GA_Offset myPtAOffset;
171  GA_Offset myPtBOffset;
172 
173  /// Track how many constraints we've seen so far.
174  exint myConstraintIndex;
175 
176  /// Primitive group containing constraints that have been broken.
177  /// These are ignored by the iterator.
178  const GA_PrimitiveGroup *myBrokenGroup;
179 
180  /// Map from the 'constraint_type' attribute's string indices to the
181  /// corresponding ConstraintType enum values.
182  UT_Array<ConstraintType> myConstraintTypes;
183 
184  /// Track whether each unique value of 'constraint_name' is a valid
185  /// constraint data type.
186  UT_BitArray myValidConstraintData;
187 
188  GA_ROHandleS myConstraintNameRef;
189  GA_ROHandleS myConstraintTypeRef;
190  };
191 
192  /// Provides a convenient way to process all of the constraints in the
193  /// network, and update attributes of the constraints.
195  {
196  public:
197  /// Use the filter parameter to process only a certain constraint type.
198  /// The default behaviour is to process everything.
199  iterator(
200  const SIM_Data &container, const SIM_Data &data_root,
201  SIM_GeometryCopy *geo, const SIM_Time &t,
202  ConstraintAccessor &constraint_accessor,
203  AnchorAccessor &anchor_accessor);
204  ~iterator();
205 
206  void rewind() { return myImpl.rewind(); }
207  bool atEnd() const { return myImpl.atEnd(); }
208  void advance() { myImpl.advance(); }
209 
210  /// Return the number of constraints that have been seen so far.
211  exint getConstraintIndex() const { return myImpl.getConstraintIndex(); }
212 
213  /// Return the primitive number corresponding to the current constraint.
214  GA_Index getPrimIndex() const { return myImpl.getPrimIndex(); }
215  GA_Offset getPrimOffset() const { return myImpl.getPrimOffset(); }
216 
217  /// Returns the index of the current constraint data type.
218  exint getConstraintDataIndex() const { return myImpl.getConstraintDataIndex(); }
219 
220  /// Return the point number corresponding to an anchor.
221  GA_Index getPointNumber(bool anchor1) const;
222 
223  GU_Detail &getGdp() const { return *myWriteableGdp; }
224 
225  /// Mark the current constraint as being broken.
226  /// This will cause it to switch to the next constraint type (if
227  /// defined) or break and be skipped on any further traversals of the
228  /// constraints. The broken constraints are placed into a primitive
229  /// group, which can then be used in a SOP solver to trigger events
230  /// when constraints break.
231  void breakConstraint();
232 
233  /// Convenience method to update the constraint about the
234  /// forces or torques applied to satisfy it.
235  void updateLinearConstraintState(fpreal force, fpreal distance);
236  void updateAngularConstraintState(fpreal torque, fpreal angle);
237 
238  /// Returns the underlying const_iterator
239  const_iterator &getConstIterator() { return myImpl; }
240 
241  private:
242  static GA_PrimitiveGroup *getBrokenGroup(GU_Detail *gdp);
243 
244  SIM_GeometryCopy *myGeoCopy;
246  GU_Detail *myWriteableGdp;
247  GA_PrimitiveGroup *myBrokenGroup;
248 
249  GA_RWHandleF myForceAttrib;
250  GA_RWHandleF myDistanceAttrib;
251  GA_RWHandleF myTorqueAttrib;
252  GA_RWHandleF myAngleAttrib;
253 
254  GA_RWHandleS myConstraintName;
255  GA_RWHandleS myConstraintType;
256  GA_RWHandleS myNextConstraintName;
257  GA_RWHandleS myNextConstraintType;
258 
259  const_iterator myImpl;
260  };
261 
262  /// Generic implementation of @ref ConstraintAccessor, which evaluates
263  /// constraint parameter values by name.
265  {
266  public:
267  /// Default constructor uses SIM_DataFilterAll.
269 
271 
272  void init(const GU_Detail *gdp, exint num_constraint_types) override;
273  bool acceptConstraint(const SIM_Data &constraint_data,
274  exint idx) override;
275 
276  /// Update the current constraint data type index and primitive offset.
277  void advance(exint constraint_idx, GA_Offset primoff);
278 
279  const SIM_Data *getConstraintData() const;
280 
281  /// Returns the value of an attribute of the constraint. If there is no
282  /// primitive attribute with that name, a default value will be taken
283  /// from the attached subdata if possible.
284  template <typename T>
285  T get(const UT_StringRef &attribute_name) const;
286 
287  /// Retrieve a value from the attached subdata for the constraint.
288  template <typename T>
289  T getDataOption(const UT_StringRef &attribute_name) const;
290 
291  /// Looks up a value for a primitive attribute.
292  /// Returns true if the attribute exists, and false otherwise.
293  template <typename T>
294  bool getPrimitiveAttribute(
295  const UT_StringRef &attribute_name, T &value) const;
296 
297  private:
299 
300  /// Looks up a value for a primitive attribute.
301  /// Returns true if the attribute exists, and false otherwise.
302  template <typename T>
303  bool getPrimitiveAttribute(
304  const UT_StringRef &attribute_name, const GU_Detail &gdp,
305  AttribCache &cache, T &value) const;
306 
307  /// Look up an attribute value. If the primitive attribute is not
308  /// present, the value from the subdata will be used.
309  template <typename T>
310  void get(const UT_StringRef &attribute_name, const GU_Detail &gdp,
311  AttribCache &cache, T &value) const;
312 
313  /// Look up a floating-point attribute value. If present, the primitive
314  /// attribute value will be multiplied with the value from the subdata.
315  void get(const UT_StringRef &attribute_name, const GU_Detail &gdp,
316  AttribCache &cache, fpreal &value) const;
317 
318  /// @{
319  /// Helper functions to look up values in a SIM_OptionsUser object.
320  static void getOption(
321  const SIM_OptionsUser *data, const UT_StringRef &attribute_name,
322  int &value)
323  {
324  value = data ? data->getOptions().getOptionI(attribute_name) : 0;
325  }
326  static void getOption(
327  const SIM_OptionsUser *data, const UT_StringRef &attribute_name,
328  fpreal &value)
329  {
330  value = data ? data->getOptions().getOptionF(attribute_name) : 0;
331  }
332 
333  static void getOption(
334  const SIM_OptionsUser *data, const UT_StringRef &attribute_name,
335  UT_Vector2 &value)
336  {
337  value = data ? data->getOptions().getOptionV2(attribute_name) :
338  UT_Vector2D(0, 0);
339  }
340 
341  static void getOption(
342  const SIM_OptionsUser *data, const UT_StringRef &attribute_name,
343  UT_Vector3 &value)
344  {
345  value = data ? data->getOptions().getOptionV3(attribute_name) :
346  UT_Vector3D(0, 0, 0);
347  }
348 
349  static void getOption(
350  const SIM_OptionsUser *data, const UT_StringRef &attribute_name,
351  UT_Quaternion &value)
352  {
353  value = data ? data->getOptions().getOptionQ(attribute_name) :
354  UT_QuaternionD(0, 0, 0, 1);
355  }
356  /// @}
357 
358  const GU_Detail *myGdp;
359  UT_Array<const SIM_Data *> myConstraintData;
360  UT_Array<const SIM_OptionsUser *> myConstraintDataOptions;
361 
362  exint myConstraintDataIndex;
363  GA_Offset myPrimOffset;
364 
365  /// Cache references to attributes.
366  mutable AttribCache myCachedAttributes;
367 
369  };
370 
371  /// Generic implementation of @ref AnchorAccessor, which builds its own
372  /// cache of the objects (transforms, etc) referenced by the anchor points.
374  {
375  public:
377 
378  bool init(
379  const GU_Detail &gdp, const UT_Matrix4D &xform,
380  const SIM_Data &container, const SIM_Data &data_root,
381  const SIM_Time &t) override;
382 
383  void advance(GA_Offset pt_a, GA_Offset pt_b)
384  {
385  myPtAOffset = pt_a;
386  myPtBOffset = pt_b;
387  }
388 
389  /// Get the point offset of the point referred to by the anchor.
390  /// Either the anchor directly references a point on an object,
391  /// or it references a vertex on an object which has an associated
392  /// point. Returns GA_INVALID_OFFSET in the case where the anchor doesnt
393  /// reference a point. If 'anchor_pid' or 'anchor_vid' is present, then
394  /// return the first point (or vertex) with same id as on the
395  /// constraint.
396  GA_Offset getAnchorPointOffset(bool anchor1) const;
397 
398  /// Gets the point index of the point referred to by the anchor in a
399  /// similar way to getAnchorPointOffset.
400  GA_Index getAnchorPointIndex(bool anchor1) const;
401 
402  UT_Vector3 getAnchorPosition(bool anchor1) const;
403  UT_Vector3 getAnchorVelocity(bool anchor1) const;
404  /// Returns the type of position described by the anchor (e.g. relative
405  /// offset).
406  PositionType getAnchorPositionType(bool anchor1) const;
407 
408  UT_Quaternion getAnchorOrientation(bool anchor1) const;
409  UT_Vector3 getAnchorAngularVelocity(bool anchor1) const;
410 
411  bool getObjectCentroid(bool anchor1, UT_Vector3 &pos) const;
412 
413  int getAnchorNumConDOFs(bool anchor1) const;
414  UT_Vector3 getAnchorDOFVector(bool anchor1) const;
415 
416  const UT_StringHolder &getAnchorName(bool anchor1) const;
417 
418  /// Returns the id of the object named by the anchor.
419  /// Returns -1 of the anchor does not name an object.
420  int getObjectId(bool anchor1) const;
421  const SIM_Object *getObject(bool anchor1) const;
422 
423  private:
424  class CachedObjectData
425  {
426  public:
427  CachedObjectData(const SIM_BaseObjectReader &reader,
428  bool need_object_geo,
429  const UT_Matrix4D *agent_xform);
430  ~CachedObjectData() {}
431 
432  const GU_Detail *getGdp() const
433  {
434  if (myGeoReadLock)
435  {
436  const GU_Detail *gdp = myGeoReadLock->getGdp();
437  UT_ASSERT(gdp);
438  return gdp;
439  }
440  else
441  return 0;
442  }
443 
444  const SIM_Object &myObject;
446 
447  UT_DMatrix4 myPosXform;
448  UT_DMatrix4 myGeoXform;
449  UT_Matrix4D myAgentXform;
450  UT_Quaternion myPosRotation;
451  UT_Quaternion myGeoRotation;
452  UT_Quaternion myAgentRotation;
453  const UT_Vector3 myCentroid;
454 
455  GA_ROHandleQ myOrientRef;
456  GA_ROHandleV3 myVelocityRef;
457  GA_ROHandleV3 myWRef;
458 
459  GA_ROHandleI myAnchorPIDRef;
460  GA_ROHandleI myAnchorVIDRef;
461  };
462 
463  /// Get the point offset of the point referenced by the anchor.
464  /// Either the anchor directly references a point on an object,
465  /// or it references a vertex on an object which has an associated
466  /// point. Returns GA_INVALID_OFFSET in the case where the anchor doesnt
467  /// reference a point
468  GA_Offset
469  getAnchorPointOffset(bool anchor1, const CachedObjectData *data) const;
470 
471  /// Returns the cached data for an anchor by looking up the name
472  const CachedObjectData *getCachedData(bool anchor1) const;
473 
474  /// Get the value in the anchor's anchor_id attribute
475  /// (-1 if no such attribute exists)
476  int getAnchorId(bool anchor1) const;
477 
478  /// Get the type of the Anchor (Point or Vertex)
479  AnchorType getAnchorType(bool anchor1) const;
480 
481  UT_Quaternion getInitialAnchorOrientation(bool anchor1) const;
482 
483  GA_StringIndexType getAnchorNameIndex(bool anchor1) const;
484 
485  SYS_FORCE_INLINE GA_Offset getPointOffset(bool anchor1) const
486  {
487  return anchor1 ? myPtBOffset : myPtAOffset;
488  }
489 
490  const GU_Detail *myGdp;
491 
492  GA_Offset myPtAOffset;
493  GA_Offset myPtBOffset;
494 
495  /// Mapping from object names to cached data necessary for certain
496  /// functions
498 
499  UT_DMatrix4 myXform;
500  UT_Quaternion myOrient;
501  const SIM_Data *myRootData;
502 
503  GA_ROHandleS myNameRef;
504  GA_ROHandleI myNumDOFsRef;
505  GA_ROHandleV3 myDOFVectorRef;
506  GA_ROHandleV3 myLocalPosRef;
507  GA_ROHandleQ myLocalOrientRef;
508  GA_ROHandleI myAnchorIdRef;
509  GA_ROHandleS myAnchorTypeRef;
510  GA_ROHandleV3 myVelocityRef;
511  GA_ROHandleV3 myRotationRef;
512  GA_ROHandleQ myOrientRef;
513  GA_ROHandleV3 myAngularVelocityRef;
514  };
515 
516 }
517 
519 
520 #endif
PositionType
How the position of the anchor is interpreted.
GA_Index getPrimIndex() const
Return the primitive number corresponding to the current constraint.
const UT_Vector2D & getOptionV2(const UT_StringRef &name) const
const_iterator & getConstIterator()
Returns the underlying const_iterator.
Iteration over a range of elements.
Definition: GA_Iterator.h:28
UT_Vector2T< fpreal64 > UT_Vector2D
exint getConstraintIndex() const
The number of valid constraints that have been seen so far.
int64 getOptionI(const UT_StringRef &name) const
const UT_Vector3D & getOptionV3(const UT_StringRef &name) const
Read-Write string handle.
Definition: GA_Handle.h:833
GA_Size GA_Offset
Definition: GA_Types.h:617
SIM_API void addTorqueAttributes(GU_Detail &gdp, GA_RWHandleF &torque, GA_RWHandleF &angle)
Creates the 'torque' and 'angle' primitive attributes.
exint getConstraintDataIndex() const
Returns the index of the current constraint data type.
SIM_API void addForceAttributes(GU_Detail &gdp, GA_RWHandleF &force, GA_RWHandleF &distance)
Creates the 'force' and 'distance' primitive attributes.
T distance(const UT_Vector4T< T > &v1, const UT_Vector4T< T > &v2)
Definition: UT_Vector4.h:698
int64 exint
Definition: SYS_Types.h:116
UT_QuaternionT< fpreal64 > UT_QuaternionD
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
T angle(const Vec2< T > &v1, const Vec2< T > &v2)
Definition: Vec2.h:472
UT_Vector3T< fpreal64 > UT_Vector3D
const UT_QuaternionD & getOptionQ(const UT_StringRef &name) const
GLboolean * data
Definition: glcorearb.h:130
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
Definition: GA_Types.h:611
const GU_Detail & getGdp() const
The constraint network geometry.
const SIM_Options & getOptions() const
GLsizei const GLfloat * value
Definition: glcorearb.h:823
double fpreal
Definition: SYS_Types.h:270
ConstraintType
The type of a constraint (linear, angular, or both).
exint getConstraintIndex() const
Return the number of constraints that have been seen so far.
#define SIM_API
Definition: SIM_API.h:10
GA_BlobIndex GA_StringIndexType
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:126
GA_Offset getPrimOffset() const
The primitive offset.
Read-only handle for string attribute data.
Definition: GA_Handle.h:756
fpreal64 getOptionF(const UT_StringRef &name) const
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1296
This implements a SIM_Geometry that copies the source geometry.