NVIDIAGameWorks / PhysX

NVIDIA PhysX SDK
Other
3.19k stars 809 forks source link

onContactModify reports the same collision twice #631

Closed pkusilence closed 1 year ago

pkusilence commented 1 year ago

Using PhysX 3.4.0 , we found that the exactly same two shapes can generate two contact modification event (both not in CCD), in one timestep. Moreover, the two collision modification event has the mContactReportStamp (which is PX_INVALID_U32, might because contact report buffer is initialiezed later ), but only once the contact will be report in "onContact" callback. At the beginning of the game, only one event will be reported, and if the same collison reported twice, all of the event is reported twice. Both actors are CCD-enabled, but all of the duplicate events are not CCD event.

image image image image

pkusilence commented 1 year ago

Last 4 days I have been debugging this problem but did not find any key clue. What I found are :

  1. It only happens probabilistically (~10%) if the two shapes of two rigidDynamic switch the collison response from PxFilterFlag::eSUPPRESS to PxFilterFlag::eDEFAULT. After the switch the ScInteraction will get refiltered and is converted to a shapeInteraction. If the two shapes are created to collide with each other at the beginning, there won't be duplicate collisions.
  2. The primary scene where duplicate collisions are generated is Sc::NPhaseCore::createRbElementInteraction, I check them as the pic shown: image
  3. After the first duplicate collisions were found, one of the contact managers is always active, even if the AABB of the shapes are separated. When the two shapes come to be in touch again, collision will be found twice again.
  4. The two duplicate collisions will go through all the pipeline of contact resolution, usually they are solved that one is given impulses to a certain value enough , and the other is given impulse nearly to zero.
  5. I can filter out duplicate collisions via contact modification, and set one of them to have zero maxImpulse, but there is still a waste of narrow phase of collision detection.
  6. It happens with and without CCD contact enabled.
pkusilence commented 1 year ago

The problem is solved, after replacing the codes of interactions by version 3.4.2 (orginal is 3.4.0). Differences are below:

  1. In constructor ShapeInteraction::ShapeInteraction, it lacks "scene.getNPhaseCore()->registerInteraction(this);" in 3.4.0;
  2. In Sc::NPhaseCore::convert, as PT described, unregisterInteraction should be done before create new shapeInteraction.
PierreTerdiman commented 1 year ago

Glad to hear this.

Yes, 3.4.0 is quite old by now and it is likely that this is not the only bug that got fixed in more recent versions.