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_PHYSICS_NX_FILTERING |
32 | #define PX_PHYSICS_NX_FILTERING |
33 | /** \addtogroup physics |
34 | @{ |
35 | */ |
36 | |
37 | #include "PxPhysXConfig.h" |
38 | #include "foundation/PxFlags.h" |
39 | |
40 | #if !PX_DOXYGEN |
41 | namespace physx |
42 | { |
43 | #endif |
44 | |
45 | class PxActor; |
46 | class PxShape; |
47 | |
48 | static const PxU32 INVALID_FILTER_PAIR_INDEX = 0xffffffff; |
49 | |
50 | /** |
51 | \brief Collection of flags describing the actions to take for a collision pair. |
52 | |
53 | @see PxPairFlags PxSimulationFilterShader.filter() PxSimulationFilterCallback |
54 | */ |
55 | struct PxPairFlag |
56 | { |
57 | enum Enum |
58 | { |
59 | /** |
60 | \brief Process the contacts of this collision pair in the dynamics solver. |
61 | |
62 | \note Only takes effect if the colliding actors are rigid bodies. |
63 | */ |
64 | eSOLVE_CONTACT = (1<<0), |
65 | |
66 | /** |
67 | \brief Call contact modification callback for this collision pair |
68 | |
69 | \note Only takes effect if the colliding actors are rigid bodies. |
70 | |
71 | @see PxContactModifyCallback |
72 | */ |
73 | eMODIFY_CONTACTS = (1<<1), |
74 | |
75 | /** |
76 | \brief Call contact report callback or trigger callback when this collision pair starts to be in contact. |
77 | |
78 | If one of the two collision objects is a trigger shape (see #PxShapeFlag::eTRIGGER_SHAPE) |
79 | then the trigger callback will get called as soon as the other object enters the trigger volume. |
80 | If none of the two collision objects is a trigger shape then the contact report callback will get |
81 | called when the actors of this collision pair start to be in contact. |
82 | |
83 | \note Only takes effect if the colliding actors are rigid bodies. |
84 | |
85 | \note Only takes effect if eDETECT_DISCRETE_CONTACT or eDETECT_CCD_CONTACT is raised |
86 | |
87 | @see PxSimulationEventCallback.onContact() PxSimulationEventCallback.onTrigger() |
88 | */ |
89 | eNOTIFY_TOUCH_FOUND = (1<<2), |
90 | |
91 | /** |
92 | \brief Call contact report callback while this collision pair is in contact |
93 | |
94 | If none of the two collision objects is a trigger shape then the contact report callback will get |
95 | called while the actors of this collision pair are in contact. |
96 | |
97 | \note Triggers do not support this event. Persistent trigger contacts need to be tracked separately by observing eNOTIFY_TOUCH_FOUND/eNOTIFY_TOUCH_LOST events. |
98 | |
99 | \note Only takes effect if the colliding actors are rigid bodies. |
100 | |
101 | \note No report will get sent if the objects in contact are sleeping. |
102 | |
103 | \note Only takes effect if eDETECT_DISCRETE_CONTACT or eDETECT_CCD_CONTACT is raised |
104 | |
105 | \note If this flag gets enabled while a pair is in touch already, there will be no eNOTIFY_TOUCH_PERSISTS events until the pair loses and regains touch. |
106 | |
107 | @see PxSimulationEventCallback.onContact() PxSimulationEventCallback.onTrigger() |
108 | */ |
109 | eNOTIFY_TOUCH_PERSISTS = (1<<3), |
110 | |
111 | /** |
112 | \brief Call contact report callback or trigger callback when this collision pair stops to be in contact |
113 | |
114 | If one of the two collision objects is a trigger shape (see #PxShapeFlag::eTRIGGER_SHAPE) |
115 | then the trigger callback will get called as soon as the other object leaves the trigger volume. |
116 | If none of the two collision objects is a trigger shape then the contact report callback will get |
117 | called when the actors of this collision pair stop to be in contact. |
118 | |
119 | \note Only takes effect if the colliding actors are rigid bodies. |
120 | |
121 | \note This event will also get triggered if one of the colliding objects gets deleted. |
122 | |
123 | \note Only takes effect if eDETECT_DISCRETE_CONTACT or eDETECT_CCD_CONTACT is raised |
124 | |
125 | @see PxSimulationEventCallback.onContact() PxSimulationEventCallback.onTrigger() |
126 | */ |
127 | eNOTIFY_TOUCH_LOST = (1<<4), |
128 | |
129 | /** |
130 | \brief Call contact report callback when this collision pair is in contact during CCD passes. |
131 | |
132 | If CCD with multiple passes is enabled, then a fast moving object might bounce on and off the same |
133 | object multiple times. Hence, the same pair might be in contact multiple times during a simulation step. |
134 | This flag will make sure that all the detected collision during CCD will get reported. For performance |
135 | reasons, the system can not always tell whether the contact pair lost touch in one of the previous CCD |
136 | passes and thus can also not always tell whether the contact is new or has persisted. eNOTIFY_TOUCH_CCD |
137 | just reports when the two collision objects were detected as being in contact during a CCD pass. |
138 | |
139 | \note Only takes effect if the colliding actors are rigid bodies. |
140 | |
141 | \note Trigger shapes are not supported. |
142 | |
143 | \note Only takes effect if eDETECT_CCD_CONTACT is raised |
144 | |
145 | @see PxSimulationEventCallback.onContact() PxSimulationEventCallback.onTrigger() |
146 | */ |
147 | eNOTIFY_TOUCH_CCD = (1<<5), |
148 | |
149 | /** |
150 | \brief Call contact report callback when the contact force between the actors of this collision pair exceeds one of the actor-defined force thresholds. |
151 | |
152 | \note Only takes effect if the colliding actors are rigid bodies. |
153 | |
154 | \note Only takes effect if eDETECT_DISCRETE_CONTACT or eDETECT_CCD_CONTACT is raised |
155 | |
156 | @see PxSimulationEventCallback.onContact() |
157 | */ |
158 | eNOTIFY_THRESHOLD_FORCE_FOUND = (1<<6), |
159 | |
160 | /** |
161 | \brief Call contact report callback when the contact force between the actors of this collision pair continues to exceed one of the actor-defined force thresholds. |
162 | |
163 | \note Only takes effect if the colliding actors are rigid bodies. |
164 | |
165 | \note If a pair gets re-filtered and this flag has previously been disabled, then the report will not get fired in the same frame even if the force threshold has been reached in the |
166 | previous one (unless #eNOTIFY_THRESHOLD_FORCE_FOUND has been set in the previous frame). |
167 | |
168 | \note Only takes effect if eDETECT_DISCRETE_CONTACT or eDETECT_CCD_CONTACT is raised |
169 | |
170 | @see PxSimulationEventCallback.onContact() |
171 | */ |
172 | eNOTIFY_THRESHOLD_FORCE_PERSISTS = (1<<7), |
173 | |
174 | /** |
175 | \brief Call contact report callback when the contact force between the actors of this collision pair falls below one of the actor-defined force thresholds (includes the case where this collision pair stops being in contact). |
176 | |
177 | \note Only takes effect if the colliding actors are rigid bodies. |
178 | |
179 | \note If a pair gets re-filtered and this flag has previously been disabled, then the report will not get fired in the same frame even if the force threshold has been reached in the |
180 | previous one (unless #eNOTIFY_THRESHOLD_FORCE_FOUND or #eNOTIFY_THRESHOLD_FORCE_PERSISTS has been set in the previous frame). |
181 | |
182 | \note Only takes effect if eDETECT_DISCRETE_CONTACT or eDETECT_CCD_CONTACT is raised |
183 | |
184 | @see PxSimulationEventCallback.onContact() |
185 | */ |
186 | eNOTIFY_THRESHOLD_FORCE_LOST = (1<<8), |
187 | |
188 | /** |
189 | \brief Provide contact points in contact reports for this collision pair. |
190 | |
191 | \note Only takes effect if the colliding actors are rigid bodies and if used in combination with the flags eNOTIFY_TOUCH_... or eNOTIFY_THRESHOLD_FORCE_... |
192 | |
193 | \note Only takes effect if eDETECT_DISCRETE_CONTACT or eDETECT_CCD_CONTACT is raised |
194 | |
195 | @see PxSimulationEventCallback.onContact() PxContactPair PxContactPair.extractContacts() |
196 | */ |
197 | eNOTIFY_CONTACT_POINTS = (1<<9), |
198 | |
199 | /** |
200 | \brief This flag is used to indicate whether this pair generates discrete collision detection contacts. |
201 | |
202 | \note Contacts are only responded to if eSOLVE_CONTACT is enabled. |
203 | */ |
204 | eDETECT_DISCRETE_CONTACT = (1<<10), |
205 | |
206 | /** |
207 | \brief This flag is used to indicate whether this pair generates CCD contacts. |
208 | |
209 | \note The contacts will only be responded to if eSOLVE_CONTACT is enabled on this pair. |
210 | \note The scene must have PxSceneFlag::eENABLE_CCD enabled to use this feature. |
211 | \note Non-static bodies of the pair should have PxRigidBodyFlag::eENABLE_CCD specified for this feature to work correctly. |
212 | \note This flag is not supported with trigger shapes. However, CCD trigger events can be emulated using non-trigger shapes |
213 | and requesting eNOTIFY_TOUCH_FOUND and eNOTIFY_TOUCH_LOST and not raising eSOLVE_CONTACT on the pair. |
214 | |
215 | @see PxRigidBodyFlag::eENABLE_CCD |
216 | @see PxSceneFlag::eENABLE_CCD |
217 | */ |
218 | eDETECT_CCD_CONTACT = (1<<11), |
219 | |
220 | /** |
221 | \brief Provide pre solver velocities in contact reports for this collision pair. |
222 | |
223 | If the collision pair has contact reports enabled, the velocities of the rigid bodies before contacts have been solved |
224 | will be provided in the contact report callback unless the pair lost touch in which case no data will be provided. |
225 | |
226 | \note Usually it is not necessary to request these velocities as they will be available by querying the velocity from the provided |
227 | PxRigidActor object directly. However, it might be the case that the velocity of a rigid body gets set while the simulation is running |
228 | in which case the PxRigidActor would return this new velocity in the contact report callback and not the velocity the simulation used. |
229 | |
230 | @see PxSimulationEventCallback.onContact(), PxContactPairVelocity, PxContactPairHeader.extraDataStream |
231 | */ |
232 | ePRE_SOLVER_VELOCITY = (1<<12), |
233 | |
234 | /** |
235 | \brief Provide post solver velocities in contact reports for this collision pair. |
236 | |
237 | If the collision pair has contact reports enabled, the velocities of the rigid bodies after contacts have been solved |
238 | will be provided in the contact report callback unless the pair lost touch in which case no data will be provided. |
239 | |
240 | @see PxSimulationEventCallback.onContact(), PxContactPairVelocity, PxContactPairHeader.extraDataStream |
241 | */ |
242 | ePOST_SOLVER_VELOCITY = (1<<13), |
243 | |
244 | /** |
245 | \brief Provide rigid body poses in contact reports for this collision pair. |
246 | |
247 | If the collision pair has contact reports enabled, the rigid body poses at the contact event will be provided |
248 | in the contact report callback unless the pair lost touch in which case no data will be provided. |
249 | |
250 | \note Usually it is not necessary to request these poses as they will be available by querying the pose from the provided |
251 | PxRigidActor object directly. However, it might be the case that the pose of a rigid body gets set while the simulation is running |
252 | in which case the PxRigidActor would return this new pose in the contact report callback and not the pose the simulation used. |
253 | Another use case is related to CCD with multiple passes enabled, A fast moving object might bounce on and off the same |
254 | object multiple times. This flag can be used to request the rigid body poses at the time of impact for each such collision event. |
255 | |
256 | @see PxSimulationEventCallback.onContact(), PxContactPairPose, PxContactPairHeader.extraDataStream |
257 | */ |
258 | eCONTACT_EVENT_POSE = (1<<14), |
259 | |
260 | eNEXT_FREE = (1<<15), //!< For internal use only. |
261 | |
262 | /** |
263 | \brief Provided default flag to do simple contact processing for this collision pair. |
264 | */ |
265 | eCONTACT_DEFAULT = eSOLVE_CONTACT | eDETECT_DISCRETE_CONTACT, |
266 | |
267 | /** |
268 | \brief Provided default flag to get commonly used trigger behavior for this collision pair. |
269 | */ |
270 | eTRIGGER_DEFAULT = eNOTIFY_TOUCH_FOUND | eNOTIFY_TOUCH_LOST | eDETECT_DISCRETE_CONTACT |
271 | }; |
272 | }; |
273 | |
274 | /** |
275 | \brief Bitfield that contains a set of raised flags defined in PxPairFlag. |
276 | |
277 | @see PxPairFlag |
278 | */ |
279 | typedef PxFlags<PxPairFlag::Enum, PxU16> PxPairFlags; |
280 | PX_FLAGS_OPERATORS(PxPairFlag::Enum, PxU16) |
281 | |
282 | |
283 | |
284 | /** |
285 | \brief Collection of flags describing the filter actions to take for a collision pair. |
286 | |
287 | @see PxFilterFlags PxSimulationFilterShader PxSimulationFilterCallback |
288 | */ |
289 | struct PxFilterFlag |
290 | { |
291 | enum Enum |
292 | { |
293 | /** |
294 | \brief Ignore the collision pair as long as the bounding volumes of the pair objects overlap. |
295 | |
296 | Killed pairs will be ignored by the simulation and won't run through the filter again until one |
297 | of the following occurs: |
298 | |
299 | \li The bounding volumes of the two objects overlap again (after being separated) |
300 | \li The user enforces a re-filtering (see #PxScene::resetFiltering()) |
301 | |
302 | @see PxScene::resetFiltering() |
303 | */ |
304 | eKILL = (1<<0), |
305 | |
306 | /** |
307 | \brief Ignore the collision pair as long as the bounding volumes of the pair objects overlap or until filtering relevant data changes for one of the collision objects. |
308 | |
309 | Suppressed pairs will be ignored by the simulation and won't make another filter request until one |
310 | of the following occurs: |
311 | |
312 | \li Same conditions as for killed pairs (see #eKILL) |
313 | \li The filter data or the filter object attributes change for one of the collision objects |
314 | |
315 | @see PxFilterData PxFilterObjectAttributes |
316 | */ |
317 | eSUPPRESS = (1<<1), |
318 | |
319 | /** |
320 | \brief Invoke the filter callback (#PxSimulationFilterCallback::pairFound()) for this collision pair. |
321 | |
322 | @see PxSimulationFilterCallback |
323 | */ |
324 | eCALLBACK = (1<<2), |
325 | |
326 | /** |
327 | \brief Track this collision pair with the filter callback mechanism. |
328 | |
329 | When the bounding volumes of the collision pair lose contact, the filter callback #PxSimulationFilterCallback::pairLost() |
330 | will be invoked. Furthermore, the filter status of the collision pair can be adjusted through #PxSimulationFilterCallback::statusChange() |
331 | once per frame (until a pairLost() notification occurs). |
332 | |
333 | @see PxSimulationFilterCallback |
334 | */ |
335 | eNOTIFY = (1<<3) | eCALLBACK, |
336 | |
337 | /** |
338 | \brief Provided default to get standard behavior: |
339 | |
340 | The application configure the pair's collision properties once when bounding volume overlap is found and |
341 | doesn't get asked again about that pair until overlap status or filter properties changes, or re-filtering is requested. |
342 | |
343 | No notification is provided when bounding volume overlap is lost |
344 | |
345 | The pair will not be killed or suppressed, so collision detection will be processed |
346 | */ |
347 | |
348 | eDEFAULT = 0 |
349 | }; |
350 | }; |
351 | |
352 | /** |
353 | \brief Bitfield that contains a set of raised flags defined in PxFilterFlag. |
354 | |
355 | @see PxFilterFlag |
356 | */ |
357 | typedef PxFlags<PxFilterFlag::Enum, PxU16> PxFilterFlags; |
358 | PX_FLAGS_OPERATORS(PxFilterFlag::Enum, PxU16) |
359 | |
360 | |
361 | /** |
362 | \brief PxFilterData is user-definable data which gets passed into the collision filtering shader and/or callback. |
363 | |
364 | @see PxShape.setSimulationFilterData() PxShape.getSimulationFilterData() PxSimulationFilterShader PxSimulationFilterCallback |
365 | */ |
366 | struct PxFilterData |
367 | { |
368 | //= ATTENTION! ===================================================================================== |
369 | // Changing the data layout of this class breaks the binary serialization format. See comments for |
370 | // PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData |
371 | // function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION |
372 | // accordingly. |
373 | //================================================================================================== |
374 | |
375 | PX_INLINE PxFilterData(const PxEMPTY) |
376 | { |
377 | } |
378 | |
379 | /** |
380 | \brief Default constructor. |
381 | */ |
382 | PX_INLINE PxFilterData() |
383 | { |
384 | word0 = word1 = word2 = word3 = 0; |
385 | } |
386 | |
387 | /** |
388 | \brief Copy constructor. |
389 | */ |
390 | PX_INLINE PxFilterData(const PxFilterData& fd) : word0(fd.word0), word1(fd.word1), word2(fd.word2), word3(fd.word3) {} |
391 | |
392 | /** |
393 | \brief Constructor to set filter data initially. |
394 | */ |
395 | PX_INLINE PxFilterData(PxU32 w0, PxU32 w1, PxU32 w2, PxU32 w3) : word0(w0), word1(w1), word2(w2), word3(w3) {} |
396 | |
397 | /** |
398 | \brief (re)sets the structure to the default. |
399 | */ |
400 | PX_INLINE void setToDefault() |
401 | { |
402 | *this = PxFilterData(); |
403 | } |
404 | |
405 | /** |
406 | \brief Assignment operator |
407 | */ |
408 | PX_INLINE void operator = (const PxFilterData& fd) |
409 | { |
410 | word0 = fd.word0; |
411 | word1 = fd.word1; |
412 | word2 = fd.word2; |
413 | word3 = fd.word3; |
414 | } |
415 | |
416 | /** |
417 | \brief Comparison operator to allow use in Array. |
418 | */ |
419 | PX_INLINE bool operator == (const PxFilterData& a) const |
420 | { |
421 | return a.word0 == word0 && a.word1 == word1 && a.word2 == word2 && a.word3 == word3; |
422 | } |
423 | |
424 | /** |
425 | \brief Comparison operator to allow use in Array. |
426 | */ |
427 | PX_INLINE bool operator != (const PxFilterData& a) const |
428 | { |
429 | return !(a == *this); |
430 | } |
431 | |
432 | PxU32 word0; |
433 | PxU32 word1; |
434 | PxU32 word2; |
435 | PxU32 word3; |
436 | }; |
437 | |
438 | |
439 | /** |
440 | \brief Identifies each type of filter object. |
441 | |
442 | @see PxGetFilterObjectType() |
443 | */ |
444 | struct PxFilterObjectType |
445 | { |
446 | enum Enum |
447 | { |
448 | /** |
449 | \brief A static rigid body |
450 | @see PxRigidStatic |
451 | */ |
452 | eRIGID_STATIC, |
453 | |
454 | /** |
455 | \brief A dynamic rigid body |
456 | @see PxRigidDynamic |
457 | */ |
458 | eRIGID_DYNAMIC, |
459 | |
460 | /** |
461 | \brief An articulation |
462 | @see PxArticulation |
463 | */ |
464 | eARTICULATION, |
465 | |
466 | //brief internal use only! |
467 | eMAX_TYPE_COUNT = 16, |
468 | |
469 | //brief internal use only! |
470 | eUNDEFINED = eMAX_TYPE_COUNT-1 |
471 | }; |
472 | }; |
473 | |
474 | |
475 | // For internal use only |
476 | struct PxFilterObjectFlag |
477 | { |
478 | enum Enum |
479 | { |
480 | eKINEMATIC = (1<<4), |
481 | eTRIGGER = (1<<5) |
482 | }; |
483 | }; |
484 | |
485 | |
486 | /** |
487 | \brief Structure which gets passed into the collision filtering shader and/or callback providing additional information on objects of a collision pair |
488 | |
489 | @see PxSimulationFilterShader PxSimulationFilterCallback getActorType() PxFilterObjectIsKinematic() PxFilterObjectIsTrigger() |
490 | */ |
491 | typedef PxU32 PxFilterObjectAttributes; |
492 | |
493 | |
494 | /** |
495 | \brief Extract filter object type from the filter attributes of a collision pair object |
496 | |
497 | \param[in] attr The filter attribute of a collision pair object |
498 | \return The type of the collision pair object. |
499 | |
500 | @see PxFilterObjectType |
501 | */ |
502 | PX_INLINE PxFilterObjectType::Enum PxGetFilterObjectType(PxFilterObjectAttributes attr) |
503 | { |
504 | return PxFilterObjectType::Enum(attr & (PxFilterObjectType::eMAX_TYPE_COUNT-1)); |
505 | } |
506 | |
507 | |
508 | /** |
509 | \brief Specifies whether the collision object belongs to a kinematic rigid body |
510 | |
511 | \param[in] attr The filter attribute of a collision pair object |
512 | \return True if the object belongs to a kinematic rigid body, else false |
513 | |
514 | @see PxRigidBodyFlag::eKINEMATIC |
515 | */ |
516 | PX_INLINE bool PxFilterObjectIsKinematic(PxFilterObjectAttributes attr) |
517 | { |
518 | return (attr & PxFilterObjectFlag::eKINEMATIC) != 0; |
519 | } |
520 | |
521 | |
522 | /** |
523 | \brief Specifies whether the collision object is a trigger shape |
524 | |
525 | \param[in] attr The filter attribute of a collision pair object |
526 | \return True if the object is a trigger shape, else false |
527 | |
528 | @see PxShapeFlag::eTRIGGER_SHAPE |
529 | */ |
530 | PX_INLINE bool PxFilterObjectIsTrigger(PxFilterObjectAttributes attr) |
531 | { |
532 | return (attr & PxFilterObjectFlag::eTRIGGER) != 0; |
533 | } |
534 | |
535 | |
536 | /** |
537 | \brief Filter shader to specify handling of collision pairs. |
538 | |
539 | Collision filtering is a mechanism to specify how a pair of potentially colliding objects should be processed by the |
540 | simulation. A pair of objects is potentially colliding if the bounding volumes of the two objects overlap. |
541 | In short, a collision filter decides whether a collision pair should get processed, temporarily ignored or discarded. |
542 | If a collision pair should get processed, the filter can additionally specify how it should get processed, for instance, |
543 | whether contacts should get resolved, which callbacks should get invoked or which reports should be sent etc. |
544 | |
545 | \note A default implementation of a filter shader is provided in the PhysX extensions library, see #PxDefaultSimulationFilterShader. |
546 | |
547 | @see PxSceneDesc.filterShader PxSimulationFilterCallback |
548 | */ |
549 | |
550 | /** |
551 | \brief Filter method to specify how a pair of potentially colliding objects should be processed. |
552 | |
553 | Return the PxFilterFlag flags and set the PxPairFlag flags to define what the simulation should do with the given collision pair. |
554 | |
555 | This methods gets called when: |
556 | \li The bounding volumes of two objects start to overlap. |
557 | \li The bounding volumes of two objects overlap and the filter data or filter attributes of one of the objects changed |
558 | \li A re-filtering was forced through resetFiltering() (see #PxScene::resetFiltering()) |
559 | \li Filtering is requested in scene queries |
560 | |
561 | \note Certain pairs of objects are always ignored and this method does not get called. This is the case for the |
562 | following pairs: |
563 | |
564 | \li Pair of static rigid actors |
565 | \li A static rigid actor and a kinematic actor (unless one is a trigger or if explicitly enabled through PxPairFilteringMode::eKEEP) |
566 | \li Two kinematic actors (unless one is a trigger or if explicitly enabled through PxPairFilteringMode::eKEEP) |
567 | \li Two jointed rigid bodies and the joint was defined to disable collision |
568 | \li Two articulation links if connected through an articulation joint |
569 | |
570 | \note This is a performance critical method and should be stateless. You should neither access external objects |
571 | from within this method nor should you call external methods that are not inlined. If you need a more complex |
572 | logic to filter a collision pair then use the filter callback mechanism for this pair (see #PxSimulationFilterCallback, |
573 | #PxFilterFlag::eCALLBACK, #PxFilterFlag::eNOTIFY). |
574 | |
575 | \param[in] attributes0 The filter attribute of the first object |
576 | \param[in] filterData0 The custom filter data of the first object |
577 | \param[in] attributes1 The filter attribute of the second object |
578 | \param[in] filterData1 The custom filter data of the second object |
579 | \param[out] pairFlags Flags giving additional information on how an accepted pair should get processed |
580 | \param[in] constantBlock The constant global filter data (see #PxSceneDesc.filterShaderData) |
581 | \param[in] constantBlockSize Size of the global filter data (see #PxSceneDesc.filterShaderDataSize) |
582 | \return Filter flags defining whether the pair should be discarded, temporarily ignored, processed and whether the |
583 | filter callback should get invoked for this pair. |
584 | |
585 | @see PxSimulationFilterCallback PxFilterData PxFilterObjectAttributes PxFilterFlag PxFilterFlags PxPairFlag PxPairFlags |
586 | */ |
587 | |
588 | typedef PxFilterFlags (*PxSimulationFilterShader) |
589 | (PxFilterObjectAttributes attributes0, PxFilterData filterData0, |
590 | PxFilterObjectAttributes attributes1, PxFilterData filterData1, |
591 | PxPairFlags& pairFlags, const void* constantBlock, PxU32 constantBlockSize); |
592 | |
593 | |
594 | |
595 | /** |
596 | \brief Filter callback to specify handling of collision pairs. |
597 | |
598 | This class is provided to implement more complex and flexible collision pair filtering logic, for instance, taking |
599 | the state of the user application into account. Filter callbacks also give the user the opportunity to track collision |
600 | pairs and update their filter state. |
601 | |
602 | You might want to check the documentation on #PxSimulationFilterShader as well since it includes more general information |
603 | on filtering. |
604 | |
605 | \note SDK state should not be modified from within the callbacks. In particular objects should not |
606 | be created or destroyed. If state modification is needed then the changes should be stored to a buffer |
607 | and performed after the simulation step. |
608 | |
609 | \note The callbacks may execute in user threads or simulation threads, possibly simultaneously. The corresponding objects |
610 | may have been deleted by the application earlier in the frame. It is the application's responsibility to prevent race conditions |
611 | arising from using the SDK API in the callback while an application thread is making write calls to the scene, and to ensure that |
612 | the callbacks are thread-safe. Return values which depend on when the callback is called during the frame will introduce nondeterminism |
613 | into the simulation. |
614 | |
615 | @see PxSceneDesc.filterCallback PxSimulationFilterShader |
616 | */ |
617 | class PxSimulationFilterCallback |
618 | { |
619 | public: |
620 | |
621 | /** |
622 | \brief Filter method to specify how a pair of potentially colliding objects should be processed. |
623 | |
624 | This method gets called when the filter flags returned by the filter shader (see #PxSimulationFilterShader) |
625 | indicate that the filter callback should be invoked (#PxFilterFlag::eCALLBACK or #PxFilterFlag::eNOTIFY set). |
626 | Return the PxFilterFlag flags and set the PxPairFlag flags to define what the simulation should do with the given |
627 | collision pair. |
628 | |
629 | \param[in] pairID Unique ID of the collision pair used to issue filter status changes for the pair (see #statusChange()) |
630 | \param[in] attributes0 The filter attribute of the first object |
631 | \param[in] filterData0 The custom filter data of the first object |
632 | \param[in] a0 Actor pointer of the first object |
633 | \param[in] s0 Shape pointer of the first object (NULL if the object has no shapes) |
634 | \param[in] attributes1 The filter attribute of the second object |
635 | \param[in] filterData1 The custom filter data of the second object |
636 | \param[in] a1 Actor pointer of the second object |
637 | \param[in] s1 Shape pointer of the second object (NULL if the object has no shapes) |
638 | \param[in,out] pairFlags In: Pair flags returned by the filter shader. Out: Additional information on how an accepted pair should get processed |
639 | \return Filter flags defining whether the pair should be discarded, temporarily ignored or processed and whether the pair |
640 | should be tracked and send a report on pair deletion through the filter callback |
641 | |
642 | @see PxSimulationFilterShader PxFilterData PxFilterObjectAttributes PxFilterFlag PxPairFlag |
643 | */ |
644 | virtual PxFilterFlags pairFound( PxU32 pairID, |
645 | PxFilterObjectAttributes attributes0, PxFilterData filterData0, const PxActor* a0, const PxShape* s0, |
646 | PxFilterObjectAttributes attributes1, PxFilterData filterData1, const PxActor* a1, const PxShape* s1, |
647 | PxPairFlags& pairFlags) = 0; |
648 | |
649 | /** |
650 | \brief Callback to inform that a tracked collision pair is gone. |
651 | |
652 | This method gets called when a collision pair disappears or gets re-filtered. Only applies to |
653 | collision pairs which have been marked as filter callback pairs (#PxFilterFlag::eNOTIFY set in #pairFound()). |
654 | |
655 | \param[in] pairID Unique ID of the collision pair that disappeared |
656 | \param[in] attributes0 The filter attribute of the first object |
657 | \param[in] filterData0 The custom filter data of the first object |
658 | \param[in] attributes1 The filter attribute of the second object |
659 | \param[in] filterData1 The custom filter data of the second object |
660 | \param[in] objectRemoved True if the pair was lost because one of the objects got removed from the scene |
661 | |
662 | @see pairFound() PxSimulationFilterShader PxFilterData PxFilterObjectAttributes |
663 | */ |
664 | virtual void pairLost( PxU32 pairID, |
665 | PxFilterObjectAttributes attributes0, |
666 | PxFilterData filterData0, |
667 | PxFilterObjectAttributes attributes1, |
668 | PxFilterData filterData1, |
669 | bool objectRemoved) = 0; |
670 | |
671 | /** |
672 | \brief Callback to give the opportunity to change the filter state of a tracked collision pair. |
673 | |
674 | This method gets called once per simulation step to let the application change the filter and pair |
675 | flags of a collision pair that has been reported in #pairFound() and requested callbacks by |
676 | setting #PxFilterFlag::eNOTIFY. To request a change of filter status, the target pair has to be |
677 | specified by its ID, the new filter and pair flags have to be provided and the method should return true. |
678 | |
679 | \note If this method changes the filter status of a collision pair and the pair should keep being tracked |
680 | by the filter callbacks then #PxFilterFlag::eNOTIFY has to be set. |
681 | |
682 | \note The application is responsible to ensure that this method does not get called for pairs that have been |
683 | reported as lost, see #pairLost(). |
684 | |
685 | \param[out] pairID ID of the collision pair for which the filter status should be changed |
686 | \param[out] pairFlags The new pairFlags to apply to the collision pair |
687 | \param[out] filterFlags The new filterFlags to apply to the collision pair |
688 | \return True if the changes should be applied. In this case the method will get called again. False if |
689 | no more status changes should be done in the current simulation step. In that case the provided flags will be discarded. |
690 | |
691 | @see pairFound() pairLost() PxFilterFlag PxPairFlag |
692 | */ |
693 | virtual bool statusChange(PxU32& pairID, PxPairFlags& pairFlags, PxFilterFlags& filterFlags) = 0; |
694 | |
695 | protected: |
696 | virtual ~PxSimulationFilterCallback() {} |
697 | }; |
698 | |
699 | struct PxPairFilteringMode |
700 | { |
701 | enum Enum |
702 | { |
703 | /** |
704 | Output pair from BP, potentially send to user callbacks, create regular interaction object. |
705 | |
706 | Enable contact pair filtering between kinematic/static or kinematic/kinematic rigid bodies. |
707 | |
708 | By default contacts between these are suppressed (see #PxFilterFlag::eSUPPRESS) and don't get reported to the filter mechanism. |
709 | Use this mode if these pairs should go through the filtering pipeline nonetheless. |
710 | |
711 | \note This mode is not mutable, and must be set in PxSceneDesc at scene creation. |
712 | */ |
713 | eKEEP, |
714 | |
715 | /** |
716 | Output pair from BP, create interaction marker. Can be later switched to regular interaction. |
717 | */ |
718 | eSUPPRESS, |
719 | |
720 | /** |
721 | Don't output pair from BP. Cannot be later switched to regular interaction, needs "resetFiltering" call. |
722 | */ |
723 | eKILL, |
724 | |
725 | /** |
726 | Default is eSUPPRESS for compatibility with previous PhysX versions. |
727 | */ |
728 | eDEFAULT = eSUPPRESS |
729 | }; |
730 | }; |
731 | |
732 | |
733 | #if !PX_DOXYGEN |
734 | } // namespace physx |
735 | #endif |
736 | |
737 | /** @} */ |
738 | #endif |
739 | |