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
27namespace physx
28{
29#endif
30
31class PxShape;
32
33/**
34\brief An array of contact points, as passed to contact modification.
35
36The word 'set' in the name does not imply that duplicates are filtered in any
37way. This initial set of contacts does potentially get reduced to a smaller
38set before being passed to the solver.
39
40You can use the accessors to read and write contact properties. The number of
41contacts is immutable, other than being able to disable contacts using ignore().
42
43@see PxContactModifyCallback, PxModifiableContact
44*/
45class PxContactSet
46{
47public:
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 headerOffset = sizeof(PxModifyContactHeader) + sizeof(PxContactPatchBase);
133 PxModifyContactHeader* header = 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 headerOffset = sizeof(PxModifyContactHeader) + sizeof(PxContactPatchBase);
173 PxModifyContactHeader* header = 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 headerOffset = sizeof(PxModifyContactHeader) + sizeof(PxContactPatchBase);
198 PxModifyContactHeader* header = 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 headerOffset = sizeof(PxModifyContactHeader) + sizeof(PxContactPatchBase);
210 PxModifyContactHeader* header = 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 headerOffset = sizeof(PxModifyContactHeader) + sizeof(PxContactPatchBase);
222 PxModifyContactHeader* header = 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 headerOffset = sizeof(PxModifyContactHeader) + sizeof(PxContactPatchBase);
234 PxModifyContactHeader* header = 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 headerOffset = sizeof(PxModifyContactHeader) + sizeof(PxContactPatchBase);
247 PxModifyContactHeader* header = 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 headerOffset = sizeof(PxModifyContactHeader) + sizeof(PxContactPatchBase);
261 PxModifyContactHeader* header = 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 headerOffset = sizeof(PxModifyContactHeader) + sizeof(PxContactPatchBase);
275 PxModifyContactHeader* header = 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 headerOffset = sizeof(PxModifyContactHeader) + sizeof(PxContactPatchBase);
289 PxModifyContactHeader* header = reinterpret_cast<PxModifyContactHeader*>(reinterpret_cast<PxU8*>(mContacts) - headerOffset);
290 header->invInertiaScale1 = scale;
291 header->flags |= PxContactHeader::eHAS_MODIFIED_MASS_RATIOS;
292 }
293
294protected:
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
307class PxContactModifyPair
308{
309public:
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
348simulation thread. It might also be necessary to make it reentrant, since some calls can be made by multi-threaded
349parts of the physics engine.
350
351You can enable the use of this contact modification callback by raising the flag PxPairFlag::eMODIFY_CONTACTS in
352the filter shader/callback (see #PxSimulationFilterShader) for a pair of rigid body objects.
353
354Please 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*/
362class PxContactModifyCallback
363{
364public:
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
378protected:
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
386simulation thread. It might also be necessary to make it reentrant, since some calls can be made by multi-threaded
387parts of the physics engine.
388
389You can enable the use of this contact modification callback by raising the flag PxPairFlag::eMODIFY_CONTACTS in
390the filter shader/callback (see #PxSimulationFilterShader) for a pair of rigid body objects.
391
392Please 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*/
400class PxCCDContactModifyCallback
401{
402public:
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
416protected:
417 virtual ~PxCCDContactModifyCallback(){}
418};
419
420
421#ifndef PX_DOXYGEN
422} // namespace physx
423#endif
424
425/** @} */
426#endif
427