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
43namespace physx
44{
45#endif
46
47class PxShape;
48
49/**
50\brief An array of contact points, as passed to contact modification.
51
52The word 'set' in the name does not imply that duplicates are filtered in any
53way. This initial set of contacts does potentially get reduced to a smaller
54set before being passed to the solver.
55
56You can use the accessors to read and write contact properties. The number of
57contacts is immutable, other than being able to disable contacts using ignore().
58
59@see PxContactModifyCallback, PxModifiableContact
60*/
61class PxContactSet
62{
63public:
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
347protected:
348
349 PX_FORCE_INLINE PxContactPatch* getPatch() const
350 {
351 const size_t headerOffset = 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
367class PxContactModifyPair
368{
369public:
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
408simulation thread. It might also be necessary to make it reentrant, since some calls can be made by multi-threaded
409parts of the physics engine.
410
411You can enable the use of this contact modification callback by raising the flag PxPairFlag::eMODIFY_CONTACTS in
412the filter shader/callback (see #PxSimulationFilterShader) for a pair of rigid body objects.
413
414Please 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*/
422class PxContactModifyCallback
423{
424public:
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
438protected:
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
446simulation thread. It might also be necessary to make it reentrant, since some calls can be made by multi-threaded
447parts of the physics engine.
448
449You can enable the use of this contact modification callback by raising the flag PxPairFlag::eMODIFY_CONTACTS in
450the filter shader/callback (see #PxSimulationFilterShader) for a pair of rigid body objects.
451
452Please 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*/
460class PxCCDContactModifyCallback
461{
462public:
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
476protected:
477 virtual ~PxCCDContactModifyCallback(){}
478};
479
480
481#if !PX_DOXYGEN
482} // namespace physx
483#endif
484
485/** @} */
486#endif
487

source code of qtquick3dphysics/src/3rdparty/PhysX/include/PxContactModifyCallback.h