Run time warning message in PX 3.3 between character controllers

  • PX 3.3
  • scene kinematic/kinematic kinematic/static enabled

Im forcing a collision by moving a controller (capsule, Z up) into another capsule (built same way), my PxUserControllerHitReport::onControllerHit() impl is called, and although I dont do anything in the call, they slide off each other and the one being hit adjusts slightly (nice, working).
But out of the blue every so often I get this message spammed into my console window:

…\SimulationController\src\ScNPhaseCore.cpp (889) : warning : Filtering: Resolving contacts between two kinematic objects is invalid. Contacts will not get resolved.

after this message starts printing, my object being controlled sometimes pops up in the air sometimes its the object controller being hit.
Whats causing this? its seems fine one second and then its not. Are these valid collisions or not?

Hi,

maybe I didnt understand you correctly, but I guess you dont use a custom filterShader.
You should use one set other flags for these PxControllers.

I guess the Samples shows [Bridge sample, U-Boot?] how to use the filterShader correctly.

Maybe you could post how you set the flags while you are creating the scene.

I was using a custom filterShader very similar to the submarine example for a while, but when it came time to handle ctrler/ctrler contacts, it would seem to fire once and then never again.

Im getting this warning using the default sim filter shader and setting the flags like this

sceneDesc.flags |= PxSceneFlag::eADAPTIVE_FORCE;
sceneDesc.flags |= PxSceneFlag::eENABLE_CCD;   // see, PxPairFlag::eCCD_LINEAR, PxRigidBodyFlag::eENABLE_CCD
sceneDesc.flags |= PxSceneFlag::eENABLE_ACTIVETRANSFORMS;
sceneDesc.filterShader = PxDefaultSimulationFilterShader;       
// kinematic/kinematic kinematic/static pass DefaultSimulationFilterShader
sceneDesc.flags |= PxSceneFlag::eENABLE_KINEMATIC_PAIRS;
sceneDesc.flags |= PxSceneFlag::eENABLE_KINEMATIC_STATIC_PAIRS;

Ive now switched back to a custom filter shader using same initialization, just changing the filter shader function pointer

// let triggers through
    if(PxFilterObjectIsTrigger(attributes0) || PxFilterObjectIsTrigger(attributes1))
    {
        pairFlags = PxPairFlag::eTRIGGER_DEFAULT;
        pairFlags |= PxPairFlag::eNOTIFY_TOUCH_PERSISTS;
        pairFlags |= PxPairFlag::eNOTIFY_TOUCH_FOUND;
        pairFlags |= PxPairFlag::eNOTIFY_TOUCH_LOST;
    return PxFilterFlag::eDEFAULT;
    }

    int bothKinematic = (int)PxFilterObjectIsKinematic(attributes0);
    bothKinematic += (int)PxFilterObjectIsKinematic(attributes1);
    if(bothKinematic == 2)
    {
        pairFlags |= PxPairFlag::eNOTIFY_TOUCH_FOUND;
        pairFlags |= PxPairFlag::eNOTIFY_TOUCH_LOST;
        pairFlags |= PxPairFlag::eNOTIFY_TOUCH_PERSISTS;
        pairFlags |= PxPairFlag::eCONTACT_DEFAULT;

    return PxFilterFlag::eDEFAULT;
    }

    // generate contacts for all that were not filtered above
    pairFlags = PxPairFlag::eCONTACT_DEFAULT;

    // trigger the contact callback for pairs (A,B) where
    // the filtermask of A contains the ID of B and vice versa.
    if((filterData0.word0 & filterData1.word1) && (filterData1.word0 & filterData0.word1)) {
        pairFlags |= PxPairFlag::eNOTIFY_TOUCH_FOUND;
    }

return PxFilterFlag::eDEFAULT;

but im still getting the same warning when they hit, and same bouncing up behavior.

Here is the problem:

int bothKinematic = (int)PxFilterObjectIsKinematic(attributes0);
bothKinematic += (int)PxFilterObjectIsKinematic(attributes1);
if(bothKinematic == 2)
{
pairFlags |= PxPairFlag::eNOTIFY_TOUCH_FOUND;
pairFlags |= PxPairFlag::eNOTIFY_TOUCH_LOST;
pairFlags |= PxPairFlag::eNOTIFY_TOUCH_PERSISTS;
pairFlags |= PxPairFlag::eCONTACT_DEFAULT;

return PxFilterFlag::eDEFAULT;
}

Look into the description of eNOTIFY_TOUCH - its only valid for rigid bodies.
Your actor is kinematic - so it cant resolve it.

This is how it works (you get onTrigger events, and onControllerHit and onShapeHit events)

bool kinematic0 = PxFilterObjectIsKinematic(attributes0);
bool kinematic1 = PxFilterObjectIsKinematic(attributes1);
	
	if (kinematic0 && kinematic1)
	{
		pairFlags = PxPairFlag::eTRIGGER_DEFAULT;
		return PxFilterFlag::eSUPPRESS;
	}

Where return PxFilterFlag::eSUPPRESS; is not needed, you can change it

Thx, that works, although Im confused why. I figured TRIGGER_DEFAULT was used for trigger volumes when objects enter the volume. It also seems to be defined as
eTRIGGER_DEFAULT = eNOTIFY_TOUCH_FOUND | eNOTIFY_TOUCH_LOST, so maybe it was the use of PERSISTS that was causing it? The flags dont seem very clear either way.