HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SIM_Collider.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 
8 #ifndef __SIM_Collider_h__
9 #define __SIM_Collider_h__
10 
11 #include "SIM_API.h"
12 #include "SIM_DataUtils.h"
13 #include "SIM_OptionsUser.h"
14 
15 class SIM_Impacts;
16 class SIM_Object;
17 class SIM_ObjectArray;
18 
19 /// This simple holder stores cache data associated with the collider.
21 {
22 public:
24 
26 };
27 
28 /// This is an abstract base class for all colliders.
29 /// A collider is any class that takes a pair of objects and generated
30 /// information about how those two objects intersect. See the
31 /// SIM_Object::getCollider() function for a description of how a
32 /// solver should determine the right SIM_Collider class to use for
33 /// a given pair of objects.
34 class SIM_API SIM_Collider : public SIM_Data,
35  public SIM_OptionsUser
36 {
37 public:
38  /// Specifies whether the object and affector need to be reversed to
39  /// perform collision detection. This flag is useful for colliders that
40  /// make assumptions about the makeup of the object and affector are
41  /// in the call to collideObjectsSubclass(). For example, the
42  /// point collider (SIM_ColliderPoint) always treats the object as
43  /// a particle system, using ray casting to follow the trajectory of
44  /// each particle. But suppose an RBD Solver has a particle system
45  /// as an affector object. The RBD Solver would find that the best
46  /// collider to use is a point collider. Rather than requiring that
47  /// the RBD Solver then somehow discover that the particle object must
48  /// always be sent as the "object" parameter, the collider can have
49  /// the reverse object roles flag turned on. Then when the RBD Solver
50  /// calls the collider with the RBD object first and the particle object
51  /// second, the collider itself will reverse the objects before passing
52  /// them on to collideObjectSubclass().
54 
55  /// Defines the possible affector types when doing collision detection.
56  typedef enum {
57  SIM_IMPACTAPPLY_NONE, /// Don't do any collision detection.
58  SIM_IMPACTAPPLY_ONEWAY, /// Object A gets Impacts from object B.
59  SIM_IMPACTAPPLY_MUTUAL, /// Object A and B both get Impacts.
60  SIM_IMPACTAPPLY_FEEDBACK /// Object A gets Impacts, B gets Feedback.
61  } SIM_ImpactApplyType;
62 
63  /// Perform the collision detection for a pair of objects.
64  /// This function calls the collideObjectsSubclass() function.
65  /// This also attempts to do collision response.
66  ///
67  /// Preconditions:
68  /// collideObjects expects that
69  /// getEngine.getObjectAtTime(object, starttime, true) results in the
70  /// object that holds the correct geometry and transform for starttime.
71  /// Similarly, passing in endtime must give an object that holds the
72  /// correct geometry and transformation for endtime.
73  /// The same principle applies to the affector.
74  /// Please note that starttime and endtime may be substep times.
75  ///
76  /// The solver that calls collideObjects may have to create substep objects
77  /// at t_start and t_end to ensure that these preconditions are met.
78  /// This is is not always needed for the affector, the affector may
79  /// belong to a solver that isn't substepping.
80  /// In that case collideObjects will use the
81  /// linear interpolations for the affector's geometry and transform.
82  ///
83  bool collideObjects(SIM_Engine &engine,
84  SIM_Object &object,
85  SIM_Object &affector,
86  const SIM_Time &starttime,
87  const SIM_Time &endtime,
88  SIM_ImpactApplyType impactapplytype,
89  int impactflags) const;
90 
91  /// This variant of the collider lets you specify a list of
92  /// cache data. The collider subclasses will search for a cache
93  /// data they like and use it. If none exists, they will build one
94  /// and add it to the list.
95  /// The caller is expected to delete any allocated cachedata.
96  bool collideObjects(SIM_Engine &engine,
97  SIM_Object &object,
98  SIM_Object &affector,
99  const SIM_Time &starttime,
100  const SIM_Time &endtime,
101  SIM_ImpactApplyType impactapplytype,
102  int impactflags,
104  UT_ValArray<SIM_ColliderCacheData *> &affectorcachedata) const;
105 
106 protected:
107  /// The SIM_Collider constructor.
108  explicit SIM_Collider(const SIM_DataFactory *factory);
109  /// The SIM_Collider destructor.
110  ~SIM_Collider() override;
111 
112  /// Finds or creates the impact data on the affector that is appropriate
113  /// for the given affector type. It also takes into account the value
114  /// of the ReverseObjectRoles flag.
115  SIM_Impacts *getObjectImpactData(SIM_Object &object,
116  SIM_ImpactApplyType impactapplytype) const;
117 
118  /// Finds or creates the impact data on the affector that is appropriate
119  /// for the given affector type. It also takes into account the value
120  /// of the ReverseObjectRoles flag.
121  SIM_Impacts *getAffectorImpactData(SIM_Object &affector,
122  SIM_ImpactApplyType impactapplytype) const;
123 
124  /// Returns true if the collideObjects function should always be
125  /// called with the affector object interpolated to the endtime.
126  /// This function just calls getAffectorInterpolatedToEndTimeSubclass().
127  bool getAffectorInterpolatedToEndTime() const;
128 
129  /// Override this method to implement your custom collision detection.
130  /// This function can access any data on the main object or affector
131  /// object. It can also add any extra data structures it needs to the
132  /// object for efficiency (rather than recalculating the extra data
133  /// each time this function is called).
134  virtual bool collideObjectsSubclass(SIM_Engine &engine,
135  SIM_Object &object,
136  SIM_Object &affector,
137  const SIM_Time &starttime,
138  const SIM_Time &endtime,
139  SIM_ImpactApplyType impactapplytype,
140  int impactflags) const;
141 
142  /// This version will default to invoking the non-cached version
143  /// of the collider.
144  /// If this is overridden, you do not need to override
145  /// collideObjectSubclass.
146  virtual bool collideObjectsCachedSubclass(SIM_Engine &engine,
147  SIM_Object &object,
148  SIM_Object &affector,
149  const SIM_Time &starttime,
150  const SIM_Time &endtime,
151  SIM_ImpactApplyType impactapplytype,
152  int impactflags,
154  UT_ValArray<SIM_ColliderCacheData *> &affectorcachedata) const;
155 
156  /// Returns true if the collideObjects function should always be
157  /// called with the affector object interpolated to the endtime.
158  /// The default implementation returns true.
159  virtual bool getAffectorInterpolatedToEndTimeSubclass() const;
160 
161 private:
164 };
165 
166 #endif
167 
#define DECLARE_STANDARD_GETCASTTOTYPE()
Definition: SIM_DataUtils.h:50
#define DECLARE_CLASSNAME(DataClass, SuperClass)
Definition: SIM_DataUtils.h:20
#define GETSET_DATA_FUNCS_B(DataName, FuncName)
virtual ~SIM_ColliderCacheData()
Definition: SIM_Collider.h:25
Holds pointers to a number of SIM_Object objects.
This simple holder stores cache data associated with the collider.
Definition: SIM_Collider.h:20
Object A gets Impacts from object B.
Definition: SIM_Collider.h:59
#define SIM_NAME_REVERSEOBJECTROLES
Definition: SIM_Names.h:177
#define SIM_API
Definition: SIM_API.h:12
Don't do any collision detection.
Definition: SIM_Collider.h:58