1 | // |
2 | // Redistribution and use in source and binary forms, with or without |
3 | // modification, are permitted provided that the following conditions |
4 | // are met: |
5 | // * Redistributions of source code must retain the above copyright |
6 | // notice, this list of conditions and the following disclaimer. |
7 | // * Redistributions in binary form must reproduce the above copyright |
8 | // notice, this list of conditions and the following disclaimer in the |
9 | // documentation and/or other materials provided with the distribution. |
10 | // * Neither the name of NVIDIA CORPORATION nor the names of its |
11 | // contributors may be used to endorse or promote products derived |
12 | // from this software without specific prior written permission. |
13 | // |
14 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY |
15 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
16 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
17 | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
18 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
19 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
20 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
21 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
22 | // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
24 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 | // |
26 | // Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved. |
27 | // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. |
28 | // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. |
29 | |
30 | |
31 | #ifndef PX_CONTACT_MODIFY_CALLBACK |
32 | #define PX_CONTACT_MODIFY_CALLBACK |
33 | /** \addtogroup physics |
34 | @{ |
35 | */ |
36 | |
37 | #include "PxPhysXConfig.h" |
38 | #include "PxShape.h" |
39 | #include "PxContact.h" |
40 | #include "foundation/PxTransform.h" |
41 | |
42 | #if !PX_DOXYGEN |
43 | namespace physx |
44 | { |
45 | #endif |
46 | |
47 | class PxShape; |
48 | |
49 | /** |
50 | \brief An array of contact points, as passed to contact modification. |
51 | |
52 | The word 'set' in the name does not imply that duplicates are filtered in any |
53 | way. This initial set of contacts does potentially get reduced to a smaller |
54 | set before being passed to the solver. |
55 | |
56 | You can use the accessors to read and write contact properties. The number of |
57 | contacts is immutable, other than being able to disable contacts using ignore(). |
58 | |
59 | @see PxContactModifyCallback, PxModifiableContact |
60 | */ |
61 | class PxContactSet |
62 | { |
63 | public: |
64 | /** |
65 | \brief Get the position of a specific contact point in the set. |
66 | |
67 | @see PxModifiableContact.point |
68 | */ |
69 | PX_FORCE_INLINE const PxVec3& getPoint(PxU32 i) const { return mContacts[i].contact; } |
70 | |
71 | /** |
72 | \brief Alter the position of a specific contact point in the set. |
73 | |
74 | @see PxModifiableContact.point |
75 | */ |
76 | PX_FORCE_INLINE void setPoint(PxU32 i, const PxVec3& p) { mContacts[i].contact = p; } |
77 | |
78 | /** |
79 | \brief Get the contact normal of a specific contact point in the set. |
80 | |
81 | @see PxModifiableContact.normal |
82 | */ |
83 | PX_FORCE_INLINE const PxVec3& getNormal(PxU32 i) const { return mContacts[i].normal; } |
84 | |
85 | /** |
86 | \brief Alter the contact normal of a specific contact point in the set. |
87 | |
88 | \note Changing the normal can cause contact points to be ignored. |
89 | |
90 | @see PxModifiableContact.normal |
91 | */ |
92 | PX_FORCE_INLINE void setNormal(PxU32 i, const PxVec3& n) |
93 | { |
94 | PxContactPatch* patch = getPatch(); |
95 | patch->internalFlags |= PxContactPatch::eREGENERATE_PATCHES; |
96 | mContacts[i].normal = n; |
97 | } |
98 | |
99 | /** |
100 | \brief Get the separation of a specific contact point in the set. |
101 | |
102 | @see PxModifiableContact.separation |
103 | */ |
104 | PX_FORCE_INLINE PxReal getSeparation(PxU32 i) const { return mContacts[i].separation; } |
105 | |
106 | /** |
107 | \brief Alter the separation of a specific contact point in the set. |
108 | |
109 | @see PxModifiableContact.separation |
110 | */ |
111 | PX_FORCE_INLINE void setSeparation(PxU32 i, PxReal s) { mContacts[i].separation = s; } |
112 | |
113 | /** |
114 | \brief Get the target velocity of a specific contact point in the set. |
115 | |
116 | @see PxModifiableContact.targetVelocity |
117 | |
118 | */ |
119 | PX_FORCE_INLINE const PxVec3& getTargetVelocity(PxU32 i) const { return mContacts[i].targetVelocity; } |
120 | |
121 | /** |
122 | \brief Alter the target velocity of a specific contact point in the set. |
123 | |
124 | @see PxModifiableContact.targetVelocity |
125 | */ |
126 | PX_FORCE_INLINE void setTargetVelocity(PxU32 i, const PxVec3& v) |
127 | { |
128 | PxContactPatch* patch = getPatch(); |
129 | patch->internalFlags |= PxContactPatch::eHAS_TARGET_VELOCITY; |
130 | mContacts[i].targetVelocity = v; |
131 | } |
132 | |
133 | /** |
134 | \brief Get the face index with respect to the first shape of the pair for a specific contact point in the set. |
135 | |
136 | @see PxModifiableContact.internalFaceIndex0 |
137 | */ |
138 | PX_FORCE_INLINE PxU32 getInternalFaceIndex0(PxU32 i) const { PX_UNUSED(i); return PXC_CONTACT_NO_FACE_INDEX; } |
139 | |
140 | /** |
141 | \brief Get the face index with respect to the second shape of the pair for a specific contact point in the set. |
142 | |
143 | @see PxModifiableContact.internalFaceIndex1 |
144 | */ |
145 | PX_FORCE_INLINE PxU32 getInternalFaceIndex1(PxU32 i) const |
146 | { |
147 | PxContactPatch* patch = getPatch(); |
148 | if (patch->internalFlags & PxContactPatch::eHAS_FACE_INDICES) |
149 | { |
150 | return reinterpret_cast<PxU32*>(mContacts + mCount)[mCount + i]; |
151 | } |
152 | return PXC_CONTACT_NO_FACE_INDEX; |
153 | } |
154 | |
155 | /** |
156 | \brief Get the maximum impulse for a specific contact point in the set. |
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 |
166 | |
167 | @see PxModifiableContact.maxImpulse |
168 | */ |
169 | PX_FORCE_INLINE void setMaxImpulse(PxU32 i, PxReal s) |
170 | { |
171 | PxContactPatch* patch = getPatch(); |
172 | patch->internalFlags |= PxContactPatch::eHAS_MAX_IMPULSE; |
173 | mContacts[i].maxImpulse = s; |
174 | } |
175 | |
176 | /** |
177 | \brief Get the restitution coefficient for a specific contact point in the set. |
178 | |
179 | @see PxModifiableContact.restitution |
180 | */ |
181 | PX_FORCE_INLINE PxReal getRestitution(PxU32 i) const { return mContacts[i].restitution; } |
182 | |
183 | /** |
184 | \brief Alter the restitution coefficient for a specific contact point in the set. |
185 | |
186 | \note Valid ranges [0,1] |
187 | |
188 | @see PxModifiableContact.restitution |
189 | */ |
190 | PX_FORCE_INLINE void setRestitution(PxU32 i, PxReal r) |
191 | { |
192 | PxContactPatch* patch = getPatch(); |
193 | patch->internalFlags |= PxContactPatch::eREGENERATE_PATCHES; |
194 | mContacts[i].restitution = r; |
195 | } |
196 | |
197 | /** |
198 | \brief Get the static friction coefficient for a specific contact point in the set. |
199 | |
200 | @see PxModifiableContact.staticFriction |
201 | */ |
202 | PX_FORCE_INLINE PxReal getStaticFriction(PxU32 i) const { return mContacts[i].staticFriction; } |
203 | |
204 | /** |
205 | \brief Alter the static friction coefficient for a specific contact point in the set. |
206 | |
207 | @see PxModifiableContact.staticFriction |
208 | */ |
209 | PX_FORCE_INLINE void setStaticFriction(PxU32 i, PxReal f) |
210 | { |
211 | PxContactPatch* patch = getPatch(); |
212 | patch->internalFlags |= PxContactPatch::eREGENERATE_PATCHES; |
213 | mContacts[i].staticFriction = f; |
214 | } |
215 | |
216 | /** |
217 | \brief Get the static friction coefficient for a specific contact point in the set. |
218 | |
219 | @see PxModifiableContact.dynamicFriction |
220 | */ |
221 | PX_FORCE_INLINE PxReal getDynamicFriction(PxU32 i) const { return mContacts[i].dynamicFriction; } |
222 | |
223 | /** |
224 | \brief Alter the static dynamic coefficient for a specific contact point in the set. |
225 | |
226 | @see PxModifiableContact.dynamic |
227 | */ |
228 | PX_FORCE_INLINE void setDynamicFriction(PxU32 i, PxReal f) |
229 | { |
230 | PxContactPatch* patch = getPatch(); |
231 | patch->internalFlags |= PxContactPatch::eREGENERATE_PATCHES; |
232 | mContacts[i].dynamicFriction = f; |
233 | } |
234 | |
235 | /** |
236 | \brief Ignore the contact point. |
237 | |
238 | 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. |
239 | */ |
240 | PX_FORCE_INLINE void ignore(PxU32 i) { setMaxImpulse(i, s: 0.0f); } |
241 | |
242 | /** |
243 | \brief The number of contact points in the set. |
244 | */ |
245 | PX_FORCE_INLINE PxU32 size() const { return mCount; } |
246 | |
247 | /** |
248 | \brief Returns the invMassScale of body 0 |
249 | |
250 | A value < 1.0 makes this contact treat the body as if it had larger mass. A value of 0.f makes this contact |
251 | 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. |
252 | */ |
253 | PX_FORCE_INLINE PxReal getInvMassScale0() const |
254 | { |
255 | PxContactPatch* patch = getPatch(); |
256 | return patch->mMassModification.mInvMassScale0; |
257 | } |
258 | |
259 | /** |
260 | \brief Returns the invMassScale of body 1 |
261 | |
262 | A value < 1.0 makes this contact treat the body as if it had larger mass. A value of 0.f makes this contact |
263 | 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. |
264 | */ |
265 | PX_FORCE_INLINE PxReal getInvMassScale1() const |
266 | { |
267 | PxContactPatch* patch = getPatch(); |
268 | return patch->mMassModification.mInvMassScale1; |
269 | } |
270 | |
271 | /** |
272 | \brief Returns the invInertiaScale of body 0 |
273 | |
274 | A value < 1.0 makes this contact treat the body as if it had larger inertia. A value of 0.f makes this contact |
275 | 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. |
276 | */ |
277 | PX_FORCE_INLINE PxReal getInvInertiaScale0() const |
278 | { |
279 | PxContactPatch* patch = getPatch(); |
280 | return patch->mMassModification.mInvInertiaScale0; |
281 | } |
282 | |
283 | /** |
284 | \brief Returns the invInertiaScale of body 1 |
285 | |
286 | A value < 1.0 makes this contact treat the body as if it had larger inertia. A value of 0.f makes this contact |
287 | 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. |
288 | */ |
289 | PX_FORCE_INLINE PxReal getInvInertiaScale1() const |
290 | { |
291 | PxContactPatch* patch = getPatch(); |
292 | return patch->mMassModification.mInvInertiaScale1; |
293 | } |
294 | |
295 | /** |
296 | \brief Sets the invMassScale of body 0 |
297 | |
298 | 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 |
299 | 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. |
300 | */ |
301 | PX_FORCE_INLINE void setInvMassScale0(const PxReal scale) |
302 | { |
303 | PxContactPatch* patch = getPatch(); |
304 | patch->mMassModification.mInvMassScale0 = scale; |
305 | patch->internalFlags |= PxContactPatch::eHAS_MODIFIED_MASS_RATIOS; |
306 | } |
307 | |
308 | /** |
309 | \brief Sets the invMassScale of body 1 |
310 | |
311 | 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 |
312 | 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. |
313 | */ |
314 | PX_FORCE_INLINE void setInvMassScale1(const PxReal scale) |
315 | { |
316 | PxContactPatch* patch = getPatch(); |
317 | patch->mMassModification.mInvMassScale1 = scale; |
318 | patch->internalFlags |= PxContactPatch::eHAS_MODIFIED_MASS_RATIOS; |
319 | } |
320 | |
321 | /** |
322 | \brief Sets the invInertiaScale of body 0 |
323 | |
324 | 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 |
325 | 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. |
326 | */ |
327 | PX_FORCE_INLINE void setInvInertiaScale0(const PxReal scale) |
328 | { |
329 | PxContactPatch* patch = getPatch(); |
330 | patch->mMassModification.mInvInertiaScale0 = scale; |
331 | patch->internalFlags |= PxContactPatch::eHAS_MODIFIED_MASS_RATIOS; |
332 | } |
333 | |
334 | /** |
335 | \brief Sets the invInertiaScale of body 1 |
336 | |
337 | 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 |
338 | 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. |
339 | */ |
340 | PX_FORCE_INLINE void setInvInertiaScale1(const PxReal scale) |
341 | { |
342 | PxContactPatch* patch = getPatch(); |
343 | patch->mMassModification.mInvInertiaScale1 = scale; |
344 | patch->internalFlags |= PxContactPatch::eHAS_MODIFIED_MASS_RATIOS; |
345 | } |
346 | |
347 | protected: |
348 | |
349 | PX_FORCE_INLINE PxContactPatch* getPatch() const |
350 | { |
351 | const size_t = sizeof(PxContactPatch)*mCount; |
352 | return reinterpret_cast<PxContactPatch*>(reinterpret_cast<PxU8*>(mContacts) - headerOffset); |
353 | } |
354 | |
355 | PxU32 mCount; //!< Number of contact points in the set |
356 | PxModifiableContact* mContacts; //!< The contact points of the set |
357 | }; |
358 | |
359 | |
360 | |
361 | /** |
362 | \brief An array of instances of this class is passed to PxContactModifyCallback::onContactModify(). |
363 | |
364 | @see PxContactModifyCallback |
365 | */ |
366 | |
367 | class PxContactModifyPair |
368 | { |
369 | public: |
370 | |
371 | /** |
372 | \brief The actors which make up the pair in contact. |
373 | |
374 | Note that these are the actors as seen by the simulation, and may have been deleted since the simulation step started. |
375 | */ |
376 | |
377 | const PxRigidActor* actor[2]; |
378 | /** |
379 | \brief The shapes which make up the pair in contact. |
380 | |
381 | Note that these are the shapes as seen by the simulation, and may have been deleted since the simulation step started. |
382 | */ |
383 | |
384 | const PxShape* shape[2]; |
385 | |
386 | /** |
387 | \brief The shape to world transforms of the two shapes. |
388 | |
389 | These are the transforms as the simulation engine sees them, and may have been modified by the application |
390 | since the simulation step started. |
391 | |
392 | */ |
393 | |
394 | PxTransform transform[2]; |
395 | |
396 | /** |
397 | \brief An array of contact points between these two shapes. |
398 | */ |
399 | |
400 | PxContactSet contacts; |
401 | }; |
402 | |
403 | |
404 | /** |
405 | \brief An interface class that the user can implement in order to modify contact constraints. |
406 | |
407 | <b>Threading:</b> It is <b>necessary</b> to make this class thread safe as it will be called in the context of the |
408 | simulation thread. It might also be necessary to make it reentrant, since some calls can be made by multi-threaded |
409 | parts of the physics engine. |
410 | |
411 | You can enable the use of this contact modification callback by raising the flag PxPairFlag::eMODIFY_CONTACTS in |
412 | the filter shader/callback (see #PxSimulationFilterShader) for a pair of rigid body objects. |
413 | |
414 | Please note: |
415 | + Raising the contact modification flag will not wake the actors up automatically. |
416 | + It is not possible to turn off the performance degradation by simply removing the callback from the scene, the |
417 | filter shader/callback has to be used to clear the contact modification flag. |
418 | + The contacts will only be reported as long as the actors are awake. There will be no callbacks while the actors are sleeping. |
419 | |
420 | @see PxScene.setContactModifyCallback() PxScene.getContactModifyCallback() |
421 | */ |
422 | class PxContactModifyCallback |
423 | { |
424 | public: |
425 | |
426 | /** |
427 | \brief Passes modifiable arrays of contacts to the application. |
428 | |
429 | The initial contacts are as determined fresh each frame by collision detection. |
430 | |
431 | The number of contacts can not be changed, so you cannot add your own contacts. You may however |
432 | disable contacts using PxContactSet::ignore(). |
433 | |
434 | @see PxContactModifyPair |
435 | */ |
436 | virtual void onContactModify(PxContactModifyPair* const pairs, PxU32 count) = 0; |
437 | |
438 | protected: |
439 | virtual ~PxContactModifyCallback(){} |
440 | }; |
441 | |
442 | /** |
443 | \brief An interface class that the user can implement in order to modify CCD contact constraints. |
444 | |
445 | <b>Threading:</b> It is <b>necessary</b> to make this class thread safe as it will be called in the context of the |
446 | simulation thread. It might also be necessary to make it reentrant, since some calls can be made by multi-threaded |
447 | parts of the physics engine. |
448 | |
449 | You can enable the use of this contact modification callback by raising the flag PxPairFlag::eMODIFY_CONTACTS in |
450 | the filter shader/callback (see #PxSimulationFilterShader) for a pair of rigid body objects. |
451 | |
452 | Please note: |
453 | + Raising the contact modification flag will not wake the actors up automatically. |
454 | + It is not possible to turn off the performance degradation by simply removing the callback from the scene, the |
455 | filter shader/callback has to be used to clear the contact modification flag. |
456 | + The contacts will only be reported as long as the actors are awake. There will be no callbacks while the actors are sleeping. |
457 | |
458 | @see PxScene.setContactModifyCallback() PxScene.getContactModifyCallback() |
459 | */ |
460 | class PxCCDContactModifyCallback |
461 | { |
462 | public: |
463 | |
464 | /** |
465 | \brief Passes modifiable arrays of contacts to the application. |
466 | |
467 | The initial contacts are as determined fresh each frame by collision detection. |
468 | |
469 | The number of contacts can not be changed, so you cannot add your own contacts. You may however |
470 | disable contacts using PxContactSet::ignore(). |
471 | |
472 | @see PxContactModifyPair |
473 | */ |
474 | virtual void onCCDContactModify(PxContactModifyPair* const pairs, PxU32 count) = 0; |
475 | |
476 | protected: |
477 | virtual ~PxCCDContactModifyCallback(){} |
478 | }; |
479 | |
480 | |
481 | #if !PX_DOXYGEN |
482 | } // namespace physx |
483 | #endif |
484 | |
485 | /** @} */ |
486 | #endif |
487 | |