NVIDIAGameWorks/PhysX

Hits post filtering and eNO_BLOCK

elderkeltir opened this issue · 1 comments

Hello!

I want to get the following behavior from cct: ignore all the non-bottom hits. thus I can pass through any walls and ceiling BUT not fall through the floor. I can't achieve this using collision groups simply because floor and a wall are the same collision group or even the same shape/actor.

in CCT module we can get onShapeHit() callback with move direction(down, side etc.) but it's not allowed to filter it here.
in postFilter() we don't have understanding of motion direction because it's triggered during overlap.
Also it's impossible to filter any hit in postFilter() because inside cct code "eNO_BLOCK" added to flags:
sceneQueryFilterData.flags |= PxQueryFlag::eNO_BLOCK; // fix for DE8255
and it's not only substite all blocks but nones as well:
if(mNoBlock) hitType = PxQueryHitType::eTOUCH;

Above code looks like a bug to me(it's impossible to skip contacts at postFilter function), but the most interesting part for me, is there mechanism to achieve desired behavior: pass through the walls but stay above ground?

Thanks!

That code with the DE8255 comment wouldn't be the right place to post-filter the objects, because there the overlap function only deals with the bounds of the characters - i.e. it gathers potential candidates for more accurate sweep tests later. You cannot filter out the objects there, because as you said the floor and the wall will be part of the same object, so you must keep that object.

I think what you would need is to add some test / filters there: https://github.com/NVIDIAGameWorks/PhysX/blob/4.1/physx/source/physxcharacterkinematic/src/CctCharacterController.cpp#L748

This line:
if((ST)(sweep_test, &volume, CurrentGeom, center, dir, C))

That line is the one that performs the actual sweep tests against the candidates gathered by the previous code. If the test returns true, a contact has been found, returned in that "C" variable. So you could perhaps test the contact's normal (C.mWorldNormal) and only keep the ones that have a vertical normal.

I didn't test it myself and it might be a fragile solution, but that's the best idea I have so far. I'm afraid the only reliable solution otherwise would be to separate floors and walls into distinct objects indeed, and use the more traditional collision groups.