HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SIM_Impacts.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_Impacts_h__
9 #define __SIM_Impacts_h__
10 
11 #include "SIM_API.h"
12 #include <UT/UT_IntArray.h>
13 #include <UT/UT_FloatArray.h>
14 #include <UT/UT_Vector3Array.h>
15 #include "SIM_DataUtils.h"
16 
17 class UT_IStream;
18 class SIM_ObjectArray;
19 
20 /// This flag is set if the given impact is intended to represent friction
21 /// between two objects, rather than the direct collision response.
22 /// If set, the "normal" represents the tangential friction direction, and
23 /// the impulse is the friction impulse.
24 #define SIM_IMPACTS_FRICTION 0x00000001
25 
26 /// This flag is set for SIM_Impacts entries that are repulsion forces
27 /// rather than inelastic collisions. Used by SIM_ColliderRepulsion.
28 #define SIM_IMPACTS_REPULSION 0x00000002
29 
30 /// This flag is set for SIM_Impact entries that represent situations where
31 /// a point is already inside an SDF. Used by SIM_ColliderPoint.
32 #define SIM_IMPACTS_POINTINSIDE 0x00000004
33 
34 /// This flag is set for cloth-volume collision.
35 #define SIM_IMPACTS_CLOTHVOLUME 0x00000008
36 
37 /// This flag is set for cloth-cloth collision.
38 #define SIM_IMPACTS_CLOTHCLOTH 0x00000010
39 
40 /// For particle collisions, particle should stop.
41 #define SIM_IMPACTS_PARTSTOP 0x00000020
42 
43 /// For particle collisions, particle should die.
44 #define SIM_IMPACTS_PARTKILL 0x00000040
45 
46 /// For particle collisions, particle should continue on course.
47 #define SIM_IMPACTS_PARTCONTINUE 0x00000080
48 
49 /// For particle collisions, particle should stick.
50 #define SIM_IMPACTS_PARTSTICK 0x00000100
51 
52 /// For particle collisions, particle should bounce.
53 #define SIM_IMPACTS_PARTBOUNCE 0x00000200
54 
55 /// Combination of all the SIM_IMPACTS_PART* flags.
56 #define SIM_IMPACTS_PARTANY (SIM_IMPACTS_PARTSTOP | \
57  SIM_IMPACTS_PARTKILL | \
58  SIM_IMPACTS_PARTCONTINUE | \
59  SIM_IMPACTS_PARTSTICK | \
60  SIM_IMPACTS_PARTBOUNCE)
61 
62 /// Used by the cloth/volume collider to indicate that an impact will require
63 /// feedback to be resolved.
64 #define SIM_IMPACTS_FEEDBACK 0x00000400
65 
66 /// Marks that this impact won't (and didn't) compute the primitive/uv
67 /// of the collision. This can accelerate collisions with SDF based
68 /// geometry by points as no ray tests are then needed against the geometry.
69 #define SIM_IMPACTS_NOPRIMUV 0x00000800
70 
71 /// Marks that this is a resting impact, ie, if the objects were ballistic,
72 /// this impact would not have occurred. These sort of impacts tend to
73 /// be generated by gravity, thus the resting nomenclature.
74 #define SIM_IMPACTS_RESTING 0x00001000
75 
76 
77 /// This class defines a SIM_Data subclass for holding collision information.
78 /// Each contact is represented by a position in simulation space, a normal
79 /// to the collision surface, the ids of the objects involved in
80 /// the contact, and the strength of the impact impulse.
81 /// Optionally, a friction impulse can also be included with the impact.
82 ///
83 /// Remember your basic physics and the definition of "impulse":
84 /// I = F * dt = m * dv
86 {
87 public:
88  /// Get the number of contacts.
89  int getNumImpacts() const;
90  /// Get the position for a particular contact.
91  /// The position is stored in simulation space.
92  const UT_Vector3 &getPosition(int index) const;
93  /// Get the normal for a particular contact, pointing away from the first
94  /// object. This value generally represents the normal of the surface at
95  /// the point of contact. This value is used to determine the
96  /// direction of the impact force at this contact point.
97  const UT_Vector3 &getNormal(int index) const;
98  /// Get the collision impulse.
99  fpreal getImpulse(int index) const;
100  /// Set the collision impulse.
101  void setImpulse(int index, fpreal impulse);
102  /// Remove the last impact
103  void removeLastImpact();
104  /// Get flags associated with the impact
105  int getFlags(int index) const;
106  /// Get the point number involved in the collision. This function may
107  /// return -1 if the point number is unknown.
108  GA_Index getPointNumber(int index) const;
109  /// Get the primitive number involved in the collision. This function
110  /// may return -1 if the primitive number is unknown.
111  int getPrimitiveNumber(int index) const;
112  /// Get the u coordinate of the primitive where the impact occurred.
113  fpreal getPrimitiveU(int index) const;
114  /// Get the v coordinate of the primitive where the impact occurred.
115  fpreal getPrimitiveV(int index) const;
116  /// Get the w coordinate of the primitive where the impact occurred.
117  fpreal getPrimitiveW(int index) const;
118  /// Get the unique id of the other object involved in a contact.
119  int getOtherObjId(int index) const;
120  /// Get the point number on the other object involved in the collision.
121  /// This function may return -1 if the point number is unknown.
122  int getOtherObjPointNumber(int index) const;
123  /// Get the primitive number on the other object involved in the collision.
124  /// This function may return -1 if the primitive number is unknown.
125  int getOtherObjPrimitiveNumber(int index) const;
126  /// Get the u coordinate of the primitive where the impact occurred
127  /// on the other object.
128  fpreal getOtherObjPrimitiveU(int index) const;
129  /// Get the v coordinate of the primitive where the impact occurred
130  /// on the other object.
131  fpreal getOtherObjPrimitiveV(int index) const;
132  /// Get the w coordinate of the primitive where the impact occurred
133  /// on the other object.
134  fpreal getOtherObjPrimitiveW(int index) const;
135  /// Get the estimated time of the collision.
136  SIM_Time getTime(int index) const;
137 
138  /// This function adds a new impact at a position in space.
139  void addPositionImpact(const UT_Vector3 &pos,
140  const UT_Vector3 &normal,
141  fpreal impulse,
142  int otherobjid,
143  int otherobjptnum,
144  int otherobjprimnum,
145  fpreal otherobjprimu,
146  fpreal otherobjprimv,
147  fpreal otherobjprimw,
148  const SIM_Time &time,
149  int flags);
150  /// This function adds a new impact at a position in space and associates
151  /// it with a particular point.
152  void addPointImpact(const UT_Vector3 &pos,
153  const UT_Vector3 &normal,
154  fpreal impulse,
155  int ptnum,
156  int otherobjid,
157  int otherobjptnum,
158  int otherobjprimnum,
159  fpreal otherobjprimu,
160  fpreal otherobjprimv,
161  fpreal otherobjprimw,
162  const SIM_Time &time,
163  int flags);
164  /// This function adds a new impact at a position in space and associates
165  /// it with a particular primitive and UV coordinate.
166  void addPrimitiveImpact(const UT_Vector3 &pos,
167  const UT_Vector3 &normal,
168  fpreal impulse,
169  int primnum,
170  fpreal primu,
171  fpreal primv,
172  fpreal primw,
173  int otherobjid,
174  int otherobjptnum,
175  int otherobjprimnum,
176  fpreal otherobjprimu,
177  fpreal otherobjprimv,
178  fpreal otherobjprimw,
179  const SIM_Time &time,
180  int flags);
181  /// Merge the impacts from another SIM_Impacts data into this one.
182  void mergeImpacts(const SIM_Impacts &src);
183 
184  /// Merge only the impacts in the given time range. This is useful for
185  /// feedback and substepping: it allows merging of feedback impacts
186  /// from the fullstep end object to a substep object.
187  void mergeImpactsInTimeRange(const SIM_Impacts &src,
188  const SIM_Time &startTime,
189  const SIM_Time &endTime);
190 
191  /// This is a very special-purpose function used by SIM_Engine.
192  /// It removes any impacts that are self-impacts or that involve
193  /// other objects that are not in the supplied object array. It
194  /// starts the search for removal at the supplied index. This is
195  /// used to eliminate impact data during feedback iteration so that
196  /// we don't end up multiply applying impacts on non-feedback objects.
197  void keepOnlyImpactsForAffectors(
198  const SIM_ObjectArray &affectors,
199  int thisobjectid,
200  int startindex);
201 
202  /// Calculates the impulses that should be applied on objects a and b.
203  /// The resulting velocity of the specified points on the two objects
204  /// after applying the impulse should be (-relvel * bounce). Either
205  /// or both of obja and objb can be null in which case the mass of
206  /// those objects is considered to be infinite. The ptnum values can
207  /// be -1 if the world space position should be used to fetch the
208  /// impulse mass matrix. The dynamicfrictionmultiplier is multiplied
209  /// by the friction value to get the dynamic friction value. The
210  /// returned impulse should be applied equally to both objects. Note
211  /// that the returned impulse may have a normal different than nml.
212  /// The normal of the returned impulse should be used, as the impact
213  /// normal, not the original nml. Otherwise the impulse magnitude will
214  /// be wrong. Also, the output normal properly accounts for friction.
215  /// However, the returned normal direction will be in the same hemisphere
216  /// as the passed in normal, so it can be used directly as the impact
217  /// normal for object a (the passed in normal is the normal on objb).
218  static UT_Vector3 getRequiredImpulse(const UT_Vector3 &worldspacepos,
219  const UT_Vector3 &nml,
220  const SIM_Object *obja,
221  GA_Index ptnuma,
222  bool objainfinitemass,
223  const SIM_Object *objb,
224  GA_Index ptnumb,
225  bool objbinfinitemass,
226  fpreal bounce,
227  fpreal friction,
228  fpreal dynamicfrictionmultiplier,
229  fpreal bounceforward,
230  bool usesdfvelocitya = false,
231  bool usepointvelocitya = true,
232  bool usesdfvelocityb = false,
233  bool usepointvelocityb = true);
234  // Same as above but the caller can explicitly supply Ka and vela.
235  static UT_Vector3 getRequiredImpulse(const UT_DMatrix3 &Ka,
236  const UT_Vector3 &vela,
237  const UT_Vector3 &worldspacepos,
238  const UT_Vector3 &nml,
239  const SIM_Object *objb,
240  GA_Index ptnumb,
241  bool objbinfinitemass,
242  fpreal bounce,
243  fpreal friction,
244  fpreal dynamicfrictionmultiplier,
245  fpreal bounceforward,
246  bool usesdfvelocityb = false,
247  bool usepointvelocityb = true);
248  // Same as above, but the caller can explicitly supplict Kb and velb,
249  // and supplies a known desired relative velocity (normal only).
250  static UT_Vector3 getRequiredImpulse(const UT_Vector3 &desiredrelvel,
251  const UT_DMatrix3 &Ka,
252  const UT_Vector3 &vela,
253  const UT_DMatrix3 &Kb,
254  const UT_Vector3 &velb,
255  const UT_Vector3 &worldspacepos,
256  const UT_Vector3 &nml,
257  fpreal friction,
258  fpreal dynamicfrictionmultiplier,
259  fpreal bounceforward);
260 
261  /// Split an impulse into normal and tangential (friction) components.
262  static void splitImpulse(const UT_Vector3 &impulse,
263  const UT_Vector3 &normal,
264  fpreal &normalImpulseLength,
265  UT_Vector3 &tangentImpulse);
266 
267 protected:
268  /// The SIM_Impacts constructor.
269  explicit SIM_Impacts(const SIM_DataFactory *factory);
270  /// The SIM_Impacts destructor.
271  ~SIM_Impacts() override;
272 
273  /// Clears out all contact information.
274  void initializeSubclass() override;
275  /// Copies the contact information from another SIM_Impacts.
276  void makeEqualSubclass(const SIM_Data *source) override;
277  /// Saves the contact information to a stream.
278  void saveSubclass(std::ostream &os) const override;
279  /// Loads contact information from a stream.
280  bool loadSubclass(UT_IStream &is) override;
281  /// Returns the total memory used by this object.
282  int64 getMemorySizeSubclass() const override;
283  /// Creates a SIM_QueryArrays object to treat impact as a record
284  SIM_Query *createQueryObjectSubclass() const override;
285 
286  /// Helper method for the loadSubclass method to resize all of our
287  /// member variable arrays.
288  void resizeArrays(int numimpacts);
289 
290  /// Remove a impact! O(n) operation. This is protected
291  /// because the use of this method is discouraged.
292  void removeImpact(int index);
293 private:
294  UT_Vector3Array myPositions;
295  UT_Vector3Array myNormals;
296  UT_FloatArray myImpulses;
297  UT_IntArray myFlags;
298  UT_IntArray myPtNums;
299  UT_IntArray myPrimNums;
300  UT_FloatArray myPrimUs;
301  UT_FloatArray myPrimVs;
302  UT_FloatArray myPrimWs;
303  UT_IntArray myOtherObjIds;
304  UT_IntArray myOtherObjPtNums;
305  UT_IntArray myOtherObjPrimNums;
306  UT_FloatArray myOtherObjPrimUs;
307  UT_FloatArray myOtherObjPrimVs;
308  UT_FloatArray myOtherObjPrimWs;
309  UT_FloatArray myTimes;
310 
313  SIM_Data,
314  "Impact Information",
316 };
317 
318 #endif
319 
virtual void makeEqualSubclass(const SIM_Data *source)
#define DECLARE_STANDARD_GETCASTTOTYPE()
Definition: SIM_DataUtils.h:50
GLbitfield flags
Definition: glcorearb.h:1596
virtual bool loadSubclass(UT_IStream &is)
GT_API const UT_StringHolder time
virtual SIM_Query * createQueryObjectSubclass() const
virtual int64 getMemorySizeSubclass() const
int getFlags(int version)
Definition: ImfVersion.h:87
#define DECLARE_DATAFACTORY(DataClass, SuperClass, Description, DopParms)
Definition: SIM_DataUtils.h:63
Holds pointers to a number of SIM_Object objects.
GLsizei GLsizei GLchar * source
Definition: glcorearb.h:803
virtual void saveSubclass(std::ostream &os) const
long long int64
Definition: SYS_Types.h:116
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
Definition: GA_Types.h:635
fpreal64 fpreal
Definition: SYS_Types.h:277
GLuint index
Definition: glcorearb.h:786
#define SIM_API
Definition: SIM_API.h:12
static const SIM_DopDescription * getEmptyDopDescription()
A DOP description that says not to create an automatic DOP.
GLenum src
Definition: glcorearb.h:1793
virtual void initializeSubclass()