1 | /* |
2 | * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. |
3 | * |
4 | * NVIDIA CORPORATION and its licensors retain all intellectual property |
5 | * and proprietary rights in and to this software, related documentation |
6 | * and any modifications thereto. Any use, reproduction, disclosure or |
7 | * distribution of this software and related documentation without an express |
8 | * license agreement from NVIDIA CORPORATION is strictly prohibited. |
9 | */ |
10 | // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. |
11 | // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. |
12 | |
13 | |
14 | #ifndef PX_CONTACT_MODIFY_CALLBACK |
15 | #define PX_CONTACT_MODIFY_CALLBACK |
16 | /** \addtogroup physics |
17 | @{ |
18 | */ |
19 | |
20 | #include "PxPhysXConfig.h" |
21 | #include "PxShape.h" |
22 | #include "PxContact.h" |
23 | #include "foundation/PxTransform.h" |
24 | |
25 | |
26 | #ifndef PX_DOXYGEN |
27 | namespace physx |
28 | { |
29 | #endif |
30 | |
31 | class PxShape; |
32 | |
33 | /** |
34 | \brief An array of contact points, as passed to contact modification. |
35 | |
36 | The word 'set' in the name does not imply that duplicates are filtered in any |
37 | way. This initial set of contacts does potentially get reduced to a smaller |
38 | set before being passed to the solver. |
39 | |
40 | You can use the accessors to read and write contact properties. The number of |
41 | contacts is immutable, other than being able to disable contacts using ignore(). |
42 | |
43 | @see PxContactModifyCallback, PxModifiableContact |
44 | */ |
45 | class PxContactSet |
46 | { |
47 | public: |
48 | /** |
49 | \brief Get the position of a specific contact point in the set. |
50 | |
51 | The contact points could be on the surface of either shape and there are currently no guarantees provided upon which shape the points lie. |
52 | |
53 | @see PxModifiableContact.point |
54 | */ |
55 | PX_FORCE_INLINE const PxVec3& getPoint(PxU32 i) const { return mContacts[i].contact; } |
56 | |
57 | /** |
58 | \brief Alter the position of a specific contact point in the set. |
59 | |
60 | @see PxModifiableContact.point |
61 | */ |
62 | PX_FORCE_INLINE void setPoint(PxU32 i, const PxVec3& p) |
63 | { |
64 | mContacts[i].contact = p; |
65 | } |
66 | |
67 | /** |
68 | \brief Get the contact normal of a specific contact point in the set. |
69 | |
70 | The contact normal points from the second shape to the first shape. |
71 | |
72 | @see PxModifiableContact.normal |
73 | */ |
74 | PX_FORCE_INLINE const PxVec3& getNormal(PxU32 i) const { return mContacts[i].normal; } |
75 | |
76 | /** |
77 | \brief Alter the contact normal of a specific contact point in the set. |
78 | |
79 | \note Changing the normal can cause contact points to be ignored. |
80 | \note This must be a normalized vector. |
81 | |
82 | @see PxModifiableContact.normal |
83 | */ |
84 | PX_FORCE_INLINE void setNormal(PxU32 i, const PxVec3& n) |
85 | { |
86 | mContacts[i].normal = n; |
87 | } |
88 | |
89 | /** |
90 | \brief Get the separation of a specific contact point in the set. |
91 | |
92 | This value can be either positive or negative. A negative value denotes penetration whereas a positive value denotes separation. |
93 | |
94 | @see PxModifiableContact.separation |
95 | */ |
96 | PX_FORCE_INLINE PxReal getSeparation(PxU32 i) const { return mContacts[i].separation; } |
97 | |
98 | /** |
99 | \brief Alter the separation of a specific contact point in the set. |
100 | |
101 | @see PxModifiableContact.separation |
102 | */ |
103 | PX_FORCE_INLINE void setSeparation(PxU32 i, PxReal s) |
104 | { |
105 | mContacts[i].separation = s; |
106 | } |
107 | |
108 | /** |
109 | \brief Get the target velocity of a specific contact point in the set. |
110 | |
111 | @see PxModifiableContact.targetVelocity |
112 | |
113 | */ |
114 | PX_FORCE_INLINE const PxVec3& getTargetVelocity(PxU32 i) const { return mContacts[i].targetVel; } |
115 | |
116 | /** |
117 | \brief Alter the target velocity of a specific contact point in the set. |
118 | |
119 | The user-defined target velocity is used to complement the normal and frictional response to a contact. The actual response to a contact depends on |
120 | the relative velocity, bounce threshold, mass properties and material properties. |
121 | |
122 | The user-defined property should be defined as a relative velocity in the space (v0 - v1), where v0 is actor[0]'s velocity and v1 is actor[1]'s velocity. |
123 | |
124 | \note Target velocity can be set in any direction and is independent of the contact normal. Any component of the target velocity that projects onto the contact normal |
125 | will affect normal response and may cause the bodies to either suck into each-other or separate. Any component of the target velocity that does not project onto the contact |
126 | normal will affect the friction response. Target velocities tangential to the contact normal can be an effective way of replicating effects like a conveyor belt. |
127 | |
128 | @see PxModifiableContact.targetVelocity |
129 | */ |
130 | PX_FORCE_INLINE void setTargetVelocity(PxU32 i, const PxVec3& v) |
131 | { |
132 | const size_t = sizeof(PxModifyContactHeader) + sizeof(PxContactPatchBase); |
133 | PxModifyContactHeader* = reinterpret_cast<PxModifyContactHeader*>(reinterpret_cast<PxU8*>(mContacts) - headerOffset); |
134 | header->flags |= PxContactHeader::eHAS_TARGET_VELOCITY; |
135 | mContacts[i].targetVel = v; |
136 | } |
137 | |
138 | /** |
139 | \brief Get the face index with respect to the first shape of the pair for a specific contact point in the set. |
140 | |
141 | @see PxModifiableContact.internalFaceIndex0 |
142 | */ |
143 | PX_FORCE_INLINE PxU32 getInternalFaceIndex0(PxU32 i) { return mContacts[i].internalFaceIndex0; } |
144 | |
145 | /** |
146 | \brief Get the face index with respect to the second shape of the pair for a specific contact point in the set. |
147 | |
148 | @see PxModifiableContact.internalFaceIndex1 |
149 | */ |
150 | PX_FORCE_INLINE PxU32 getInternalFaceIndex1(PxU32 i) { return mContacts[i].internalFaceIndex1; } |
151 | |
152 | /** |
153 | \brief Get the maximum impulse for a specific contact point in the set. |
154 | |
155 | The value of maxImpulse is a real value in the range [0, PX_MAX_F32]. A value of 0 will disable the contact. The applied impulse will be clamped such that it |
156 | cannot exceed the max impulse. |
157 | |
158 | @see PxModifiableContact.maxImpulse |
159 | */ |
160 | PX_FORCE_INLINE PxReal getMaxImpulse(PxU32 i) const { return mContacts[i].maxImpulse; } |
161 | |
162 | /** |
163 | \brief Alter the maximum impulse for a specific contact point in the set. |
164 | |
165 | \note Must be nonnegative. If set to zero, the contact point will be ignored, otherwise the impulse applied inside the solver will be clamped such that it cannot |
166 | exceed this value. |
167 | |
168 | @see PxModifiableContact.maxImpulse |
169 | */ |
170 | PX_FORCE_INLINE void setMaxImpulse(PxU32 i, PxReal s) |
171 | { |
172 | const size_t = sizeof(PxModifyContactHeader) + sizeof(PxContactPatchBase); |
173 | PxModifyContactHeader* = reinterpret_cast<PxModifyContactHeader*>(reinterpret_cast<PxU8*>(mContacts) - headerOffset); |
174 | header->flags |= PxContactHeader::eHAS_MAX_IMPULSE; |
175 | mContacts[i].maxImpulse = s; |
176 | } |
177 | |
178 | /** |
179 | \brief Ignore the contact point. |
180 | |
181 | If a contact point is ignored then no force will get applied at this point. This can be used to disable collision in certain areas of a shape, for example. |
182 | */ |
183 | PX_FORCE_INLINE void ignore(PxU32 i) { mContacts[i].maxImpulse = 0.f; } |
184 | |
185 | /** |
186 | \brief The number of contact points in the set. |
187 | */ |
188 | PX_FORCE_INLINE PxU32 size() const { return mCount; } |
189 | |
190 | /** |
191 | \brief Returns the invMassScale of body 0 |
192 | |
193 | The scale is defaulted to 1.0, meaning that the body's true mass will be used. |
194 | */ |
195 | PX_FORCE_INLINE PxReal getInvMassScale0() const |
196 | { |
197 | const size_t = sizeof(PxModifyContactHeader) + sizeof(PxContactPatchBase); |
198 | PxModifyContactHeader* = reinterpret_cast<PxModifyContactHeader*>(reinterpret_cast<PxU8*>(mContacts) - headerOffset); |
199 | return header->invMassScale0; |
200 | } |
201 | |
202 | /** |
203 | \brief Returns the invMassScale of body 1 |
204 | |
205 | The scale is defaulted to 1.0, meaning that the body's true mass will be used. |
206 | */ |
207 | PX_FORCE_INLINE PxReal getInvMassScale1() const |
208 | { |
209 | const size_t = sizeof(PxModifyContactHeader) + sizeof(PxContactPatchBase); |
210 | PxModifyContactHeader* = reinterpret_cast<PxModifyContactHeader*>(reinterpret_cast<PxU8*>(mContacts) - headerOffset); |
211 | return header->invMassScale1; |
212 | } |
213 | |
214 | /** |
215 | \brief Returns the invInertiaScale of body 0 |
216 | |
217 | The scale is defaulted to 1.0, meaning that the body's true invInertia will be used. |
218 | */ |
219 | PX_FORCE_INLINE PxReal getInvInertiaScale0() const |
220 | { |
221 | const size_t = sizeof(PxModifyContactHeader) + sizeof(PxContactPatchBase); |
222 | PxModifyContactHeader* = reinterpret_cast<PxModifyContactHeader*>(reinterpret_cast<PxU8*>(mContacts) - headerOffset); |
223 | return header->invInertiaScale0; |
224 | } |
225 | |
226 | /** |
227 | \brief Returns the invInertiaScale of body 1 |
228 | |
229 | The scale is defaulted to 1.0, meaning that the body's true invInertia will be used. |
230 | */ |
231 | PX_FORCE_INLINE PxReal getInvInertiaScale1() const |
232 | { |
233 | const size_t = sizeof(PxModifyContactHeader) + sizeof(PxContactPatchBase); |
234 | PxModifyContactHeader* = reinterpret_cast<PxModifyContactHeader*>(reinterpret_cast<PxU8*>(mContacts) - headerOffset); |
235 | return header->invInertiaScale1; |
236 | } |
237 | |
238 | /** |
239 | \brief Sets the invMassScale of body 0 |
240 | |
241 | This can be set to any value in the range [0, PX_MAX_F32). A value < 1.0 makes this contact treat the body as if it had larger mass. A value of 0.f makes this contact |
242 | treat the body as if it had infinite mass. Any value > 1.f makes this contact treat the body as if it had smaller mass. |
243 | */ |
244 | PX_FORCE_INLINE void setInvMassScale0(const PxReal scale) |
245 | { |
246 | const size_t = sizeof(PxModifyContactHeader) + sizeof(PxContactPatchBase); |
247 | PxModifyContactHeader* = reinterpret_cast<PxModifyContactHeader*>(reinterpret_cast<PxU8*>(mContacts) - headerOffset); |
248 | header->invMassScale0 = scale; |
249 | header->flags |= PxContactHeader::eHAS_MODIFIED_MASS_RATIOS; |
250 | } |
251 | |
252 | /** |
253 | \brief Sets the invMassScale of body 1 |
254 | |
255 | This can be set to any value in the range [0, PX_MAX_F32). A value < 1.0 makes this contact treat the body as if it had larger mass. A value of 0.f makes this contact |
256 | treat the body as if it had infinite mass. Any value > 1.f makes this contact treat the body as if it had smaller mass. |
257 | */ |
258 | PX_FORCE_INLINE void setInvMassScale1(const PxReal scale) |
259 | { |
260 | const size_t = sizeof(PxModifyContactHeader) + sizeof(PxContactPatchBase); |
261 | PxModifyContactHeader* = reinterpret_cast<PxModifyContactHeader*>(reinterpret_cast<PxU8*>(mContacts) - headerOffset); |
262 | header->invMassScale1 = scale; |
263 | header->flags |= PxContactHeader::eHAS_MODIFIED_MASS_RATIOS; |
264 | } |
265 | |
266 | /** |
267 | \brief Sets the invInertiaScale of body 0 |
268 | |
269 | This can be set to any value in the range [0, PX_MAX_F32). A value < 1.0 makes this contact treat the body as if it had larger inertia. A value of 0.f makes this contact |
270 | treat the body as if it had infinite inertia. Any value > 1.f makes this contact treat the body as if it had smaller inertia. |
271 | */ |
272 | PX_FORCE_INLINE void setInvInertiaScale0(const PxReal scale) |
273 | { |
274 | const size_t = sizeof(PxModifyContactHeader) + sizeof(PxContactPatchBase); |
275 | PxModifyContactHeader* = reinterpret_cast<PxModifyContactHeader*>(reinterpret_cast<PxU8*>(mContacts) - headerOffset); |
276 | header->invInertiaScale0 = scale; |
277 | header->flags |= PxContactHeader::eHAS_MODIFIED_MASS_RATIOS; |
278 | } |
279 | |
280 | /** |
281 | \brief Sets the invInertiaScale of body 1 |
282 | |
283 | This can be set to any value in the range [0, PX_MAX_F32). A value < 1.0 makes this contact treat the body as if it had larger inertia. A value of 0.f makes this contact |
284 | treat the body as if it had infinite inertia. Any value > 1.f makes this contact treat the body as if it had smaller inertia. |
285 | */ |
286 | PX_FORCE_INLINE void setInvInertiaScale1(const PxReal scale) |
287 | { |
288 | const size_t = sizeof(PxModifyContactHeader) + sizeof(PxContactPatchBase); |
289 | PxModifyContactHeader* = reinterpret_cast<PxModifyContactHeader*>(reinterpret_cast<PxU8*>(mContacts) - headerOffset); |
290 | header->invInertiaScale1 = scale; |
291 | header->flags |= PxContactHeader::eHAS_MODIFIED_MASS_RATIOS; |
292 | } |
293 | |
294 | protected: |
295 | PxU32 mCount; //!< Number of contact points in the set |
296 | PxModifiableContact* mContacts; //!< The contact points of the set |
297 | }; |
298 | |
299 | |
300 | |
301 | /** |
302 | \brief An array of instances of this class is passed to PxContactModifyCallback::onContactModify(). |
303 | |
304 | @see PxContactModifyCallback |
305 | */ |
306 | |
307 | class PxContactModifyPair |
308 | { |
309 | public: |
310 | |
311 | /** |
312 | \brief The actors which make up the pair in contact. |
313 | |
314 | Note that these are the actors as seen by the simulation, and may have been deleted since the simulation step started. |
315 | */ |
316 | |
317 | const PxRigidActor* actor[2]; |
318 | /** |
319 | \brief The shapes which make up the pair in contact. |
320 | |
321 | Note that these are the shapes as seen by the simulation, and may have been deleted since the simulation step started. |
322 | */ |
323 | |
324 | const PxShape* shape[2]; |
325 | |
326 | /** |
327 | \brief The shape to world transforms of the two shapes. |
328 | |
329 | These are the transforms as the simulation engine sees them, and may have been modified by the application |
330 | since the simulation step started. |
331 | |
332 | */ |
333 | |
334 | PxTransform transform[2]; |
335 | |
336 | /** |
337 | \brief An array of contact points between these two shapes. |
338 | */ |
339 | |
340 | PxContactSet contacts; |
341 | }; |
342 | |
343 | |
344 | /** |
345 | \brief An interface class that the user can implement in order to modify contact constraints. |
346 | |
347 | <b>Threading:</b> It is <b>necessary</b> to make this class thread safe as it will be called in the context of the |
348 | simulation thread. It might also be necessary to make it reentrant, since some calls can be made by multi-threaded |
349 | parts of the physics engine. |
350 | |
351 | You can enable the use of this contact modification callback by raising the flag PxPairFlag::eMODIFY_CONTACTS in |
352 | the filter shader/callback (see #PxSimulationFilterShader) for a pair of rigid body objects. |
353 | |
354 | Please note: |
355 | + Raising the contact modification flag will not wake the actors up automatically. |
356 | + It is not possible to turn off the performance degradation by simply removing the callback from the scene, the |
357 | filter shader/callback has to be used to clear the contact modification flag. |
358 | + The contacts will only be reported as long as the actors are awake. There will be no callbacks while the actors are sleeping. |
359 | |
360 | @see PxScene.setContactModifyCallback() PxScene.getContactModifyCallback() |
361 | */ |
362 | class PxContactModifyCallback |
363 | { |
364 | public: |
365 | |
366 | /** |
367 | \brief Passes modifiable arrays of contacts to the application. |
368 | |
369 | The initial contacts are as determined fresh each frame by collision detection. |
370 | |
371 | The number of contacts can not be changed, so you cannot add your own contacts. You may however |
372 | disable contacts using PxContactSet::ignore(). |
373 | |
374 | @see PxContactModifyPair |
375 | */ |
376 | virtual void onContactModify(PxContactModifyPair* const pairs, PxU32 count) = 0; |
377 | |
378 | protected: |
379 | virtual ~PxContactModifyCallback(){} |
380 | }; |
381 | |
382 | /** |
383 | \brief An interface class that the user can implement in order to modify CCD contact constraints. |
384 | |
385 | <b>Threading:</b> It is <b>necessary</b> to make this class thread safe as it will be called in the context of the |
386 | simulation thread. It might also be necessary to make it reentrant, since some calls can be made by multi-threaded |
387 | parts of the physics engine. |
388 | |
389 | You can enable the use of this contact modification callback by raising the flag PxPairFlag::eMODIFY_CONTACTS in |
390 | the filter shader/callback (see #PxSimulationFilterShader) for a pair of rigid body objects. |
391 | |
392 | Please note: |
393 | + Raising the contact modification flag will not wake the actors up automatically. |
394 | + It is not possible to turn off the performance degradation by simply removing the callback from the scene, the |
395 | filter shader/callback has to be used to clear the contact modification flag. |
396 | + The contacts will only be reported as long as the actors are awake. There will be no callbacks while the actors are sleeping. |
397 | |
398 | @see PxScene.setContactModifyCallback() PxScene.getContactModifyCallback() |
399 | */ |
400 | class PxCCDContactModifyCallback |
401 | { |
402 | public: |
403 | |
404 | /** |
405 | \brief Passes modifiable arrays of contacts to the application. |
406 | |
407 | The initial contacts are as determined fresh each frame by collision detection. |
408 | |
409 | The number of contacts can not be changed, so you cannot add your own contacts. You may however |
410 | disable contacts using PxContactSet::ignore(). |
411 | |
412 | @see PxContactModifyPair |
413 | */ |
414 | virtual void onCCDContactModify(PxContactModifyPair* const pairs, PxU32 count) = 0; |
415 | |
416 | protected: |
417 | virtual ~PxCCDContactModifyCallback(){} |
418 | }; |
419 | |
420 | |
421 | #ifndef PX_DOXYGEN |
422 | } // namespace physx |
423 | #endif |
424 | |
425 | /** @} */ |
426 | #endif |
427 | |