| 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 | |