Physx SDK and PxControllerFilterCallback::filter() are VERY slow

Started by
6 comments, last by Mbrpistoni 9 years, 1 month ago

Hi!
I have a game where there are enemies. Those enemies ar CharacterControllers, which I move through PxCharacterController.move() function.
Thing is that I don't want alive enemies to collide with dead enemies. Dead enemies bodies are keeped on the ground, but I still need those dead bodies to keep their CharacterController because I do some other things with them.
To accomplish that I made my EnemiCharacterController class inherit from PxControllerFilterCallback and implement filter() function
bool PxControllerFilterCallback::filter(const PxController& a, const PxController& b) = 0;

Inside filter() I look for an uint that I previously stored in the UserData of each actor when the enemy dies.
If that uint == a value I got to identify dead corpses, I return false (don't calculate collision). Else true.

Problem here is that FPS goes down, very deep down (not playable).

My question is: is there a better way to filter Character Controller vs Character Controller collisions?
Is there a good way to improve performance?

That's the code, Just in case you see something wierd

bool TCompCharacterController::filter(const physx::PxController& a, const physx::PxController& b)
{
uint32_t tagA = (uint32_t)a.getUserData();
uint32_t tagB = (uint32_t)b.getUserData();

if (GCONST_TAGS_ENEMY_DEAD == tagA || GCONST_TAGS_ENEMY_DEAD == tagB)
return false;

return true;
}

Thanks a lot

Advertisement

Are you sure this is the source of the slow down? Nothing about that call should have that great an impact on performance. I use that callback myself and never experienced anything like this.

Hi! Thanks for answering.

I think those lines are the problem, but not for what they but how I use It. I'll try to explain.

My game engine relies on a Handlers-component system. Every element in the game is an entity wich have components. In this case I have the Enemy Entity. Every enemy is an instance of this entity. This entity has a CharacterController component. This component is the one that implements the callback and all the other things you normally use in a character controller. If you follow me, you can see that, for each enemy in the game, I have a callback filter. There are 36 enemies, so 36 callbacks working.

Should I have one static filter and make all enemies use it? Is it a good Idea to have diferent filters?

Thanks

Whether you have single callback used across all move() calls or 36, I dont see how it would matter, the callback will only be called when two controllers come into contact and again, even if they were contacting a lot, the filter doesnt do anything significant. If it returns false no collision calculations would be done at all.

The filter is being used correctly for the correct purpose, I have objects which each have an instance of this filter implemented for their move() calls and it doesnt affect performance.

At this point you might want to try a single static filter just to see what happens, but logically I cant see it making a difference. Which version of physx is this?

Hi again. I just tested the static filter and does the same. Physx is last version (currently 3.3.2). Visual Studio 2013 (in case that matters)

May I be missing something?

in the physx::PxControllerFilters I'm only setting this parameter

controllerFilters.mCCTFilterCallback = &collisionFilter; where collisionFilter is an instance of an static class that inherits from PxControllerFilterCallback.

The rest of the parameters are not being set because I tested those yesterday and I did not see any difference (they are commented as you can see).

/*

filterData.word0 = FilterGroup::eENEMYALIVE;
filterData.word1 = FilterGroup::eENEMYALIVE | FilterGroup::eBULLETS;
controllerFilters.mFilterData = &filterData;
controllerFilters.mFilterFlags = physx::PxQueryFlag::eSTATIC | physx::PxQueryFlag::eDYNAMIC;
*/

That's my move function

physx::PxControllerCollisionFlags collisionFlags = capsuleController->move(
Physics.XMVECTORToPxVec3(delta_pos),
0.01f,
physx::PxF32(elapsed),
controllerFilters,
NULL);

thanks a lot for your time

UPDATE:

Using Nvidia debugger I have observed 2 thigs:

1. collisions are allways been checked on every frame every time a character controller moves. If I change the flag controllerFilters.mFilterFlags = physx::PxQueryFlag::eSTATIC | physx::PxQueryFlag::eDYNAMIC; and set it to check only DYNAMIC, character controllers falls through the ground. It's like it's checking every collision AABB are having against the floor

2. AABB are way too big on the player, Enemies have a big one too, but still goes underground. screenshot http://imgur.com/PBETICO

So youre saying that if you set this line, controllerFilters.mCCTFilterCallback = &collisionFilter;, it becomes unplayable? Do the aabb's around the capsules also become enlarged like they are in the image? because if those are the aabb;s for the capsule controllers they should be much tighter. Unless you have modified them in some way (and Im unaware of any way to do that) or they are bounding some objects that are not showing, the extents should probably be touching the top caps and the sides.

Im using a slightly older version of physx, 3.3.0. Have you tried posting on the nvidia physx forums, it may take a week or so be you get a reply (if at all) but at this point im wondering if its not bug of some sort. Unless its some sort of scale related problem.

Yes, that line activates my custom filter (the one I already posted) and not only not improves the game, It becames unplayable (dropes to 10 fps).

The posted image is an screenshot of my game in visual debugger. Those are my current AABB. I have check my code, line by line, and I can't see where I'm modifing the AABB. I have read the documentation and I don't even find a way to do It.

There are no hiden objects, everything is being shown.

I followed your advice and post it on Nvidia forums (just the part of the AABB). There's always hope.

About the scale... I'm gonna check It. I'm exporting the meshes from 3dMax with a custom exporter. There's a chance.

Anyway, thanks a lot for your help. I will post the solution (If I find It).

Cheers

Well, 2 of my main problems are solved.

Frist problem was that FPS were down to 9 - 10. Problem was I was misusing the flags. At first I thought that those had no effect on the Character Controller, I was totally wrong. Character Controller filters relies on both, flags and callback method.

CHARACTER CONTROLLER

//filter data to make collision callback work
filterData.word0 = FilterGroup::eENEMYALIVE;
filterData.word1 = FilterGroup::eENEMYALIVE | FilterGroup::eBULLETS;
controllerFilters.mFilterData = &filterData;
controllerFilters.mCCTFilterCallback = &collisionFilter;
controllerFilters.mFilterFlags = physx::PxQueryFlag::eSTATIC | physx::PxQueryFlag::eDYNAMIC;

//set the tag to userData to allow collision callback access
TCompTags* tags = e->get<TCompTags>();
uint32_t tag = tags->getTag();
capsuleControllerDesc.userData = (void *)tag;

CODE OF FILTER() WITHIN MY CLASS CCharacterControllerFilter : public physx::PxControllerFilterCallback

bool CCharacterControllerFilter::filter(const physx::PxController& a, const physx::PxController& b)
{
uint32_t tagA = (uint32_t)a.getUserData();
uint32_t tagB = (uint32_t)b.getUserData();

if (GCONST_TAGS_ENEMY_DEAD == tagA || GCONST_TAGS_ENEMY_DEAD == tagB)
return false;

return true;
}

2. The second problem was that alive enemies where not "listening" the filters and they keept colliding with the dead enemies. It was a tricky problem. I had and avoidance logic between enemies so the don't collapse when chasing or taunt the player. It just happened that my avoid distance was EXACTLY the with size of the AABB that Physx use for the capsules. So, when I looked into Visual Debugger, what seems like collision detection, really was my avoidance logic. As soon as I assured that avoidance only happen between alive enemies, problem solved!

As soon as I got answer from Nvidia I will post why AABB are so tall (and random). http://imgur.com/PBETICO

This topic is closed to new replies.

Advertisement