How to disable BroadPhaseCollision temporary for a body?

Post Reply
donggas90
Posts: 17
Joined: Tue May 19, 2015 10:01 am

How to disable BroadPhaseCollision temporary for a body?

Post by donggas90 »

I want to toggle the collision enable state of a body to optimize my tons of bodies without add or remove from world.
(Want to control broad phase that is AABB test query NOT narrow phase.)
Ultimately, want to avoid that a disabled body generate latent collision pairs.
(I known that the needsCollision() in dispatcher, but it would call after AABB test query, so it is not a solution for this.)
Many disables and enables are there in CollisionObject so couldn't figure out which one is the best for me.
Would anyone help me?
Thanks.
donggas90
Posts: 17
Joined: Tue May 19, 2015 10:01 am

Re: How to disable BroadPhaseCollision temporary for a body?

Post by donggas90 »

Maybe create my own BroadphaseInterface can be a solution.
but it has no comments so don't know what should I implement from it.
Does anyone know about BroadphaseInterface or some docs for it?
donggas90
Posts: 17
Joined: Tue May 19, 2015 10:01 am

Re: How to disable BroadPhaseCollision temporary for a body?

Post by donggas90 »

OK, now I created my own Broadphase from SimpleBroadphase.
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: How to disable BroadPhaseCollision temporary for a body?

Post by drleviathan »

Maybe use the collision groups feature? You could make a "collisionless" group and then zero that bit in the masks that correspond to all other groups.

Edit: After thinking about this a bit more I don't think swapping collision groups is going to work for you because this feature needs to work before the broadphase overlapping pairs are created. That is, when you change the group/mask you have to flush the existing overlaps and create new ones (if any) and the easiest way to do this is to remove and re-add the object in the world, which is the expensive operation you want to avoid.

Nevertheless, there are some other methods of disabling collisions mentioned in that wiki link above that might work for you.
donggas90
Posts: 17
Joined: Tue May 19, 2015 10:01 am

Re: How to disable BroadPhaseCollision temporary for a body?

Post by donggas90 »

drleviathan wrote:Maybe use the collision groups feature? You could make a "collisionless" group and then zero that bit in the masks that correspond to all other groups.
Thanks for answer.
I had remodeled the broadphase detection and pair generation system to retain flexibility and to add my own features.
In my broadphase, Bullet's group and mask do not use. instead, my own CollisionChannels and CollisionResponse.
If you used PhysX, these would be familiar.
drleviathan wrote:Edit: After thinking about this a bit more I don't think swapping collision groups is going to work for you because this feature needs to work before the broadphase overlapping pairs are created. That is, when you change the group/mask you have to flush the existing overlaps and create new ones (if any) and the easiest way to do this is to remove and re-add the object in the world, which is the expensive operation you want to avoid.
That's right.
In remodeling, I recognized that calculation of group and mask working before pair generation.
(We can see it at btHashedOverlappingPairCache::needsBroadphaseCollision() in btHashedOverlappingPairCache::addOverlappingPair())
but I have not satisfied them since known about them.
because they cannot change in simulation without add and remove their bodies as you said.
I thought, it's non-sense and short is too small.
so planned my own group and mask system, the CollisionChannels that is a int flags and it stored out of engine's memory by user pointer thus can set or get anywhere-anytime but it works properly when using remodeled classes.
Of cource, need little more resources when generate pairs but I don't think it's a big deal.
gdlk
Posts: 62
Joined: Fri Oct 24, 2014 7:01 pm

Re: How to disable BroadPhaseCollision temporary for a body?

Post by gdlk »

Hi!

Could you give some tips how implement that (for example what is the main method to modify)? (I had the same problem (too much objects to remove/readd to the world) and forceActivationState(DISABLE_SIMULATION) is not doing the work =( )

Thanks!!
dern23
Posts: 26
Joined: Thu Oct 04, 2012 1:58 pm

Re: How to disable BroadPhaseCollision temporary for a body?

Post by dern23 »

To disable one object in the broadphase at runtime, the way to do it without modifying the API is to first clear any broadphase pairs containing the body by calling btCollisionWorld::getPairCache()->removeOverlappingPairsContainingProxy(btBroadphaseProxy*, btDispatcher*). Then to prevent the body being adding in again during the next processCollision call, you'll need to have set a custom btOverlapFilterCallback in the pair cache; I typically derive a child class from it and override the needBroadphaseCollision method. There you can return false if the body's broadphase proxy that you wish to disable is one of the arguments passed to the overridden method.
gdlk
Posts: 62
Joined: Fri Oct 24, 2014 7:01 pm

Re: How to disable BroadPhaseCollision temporary for a body?

Post by gdlk »

Thanks!! =D
donggas90
Posts: 17
Joined: Tue May 19, 2015 10:01 am

Re: How to disable BroadPhaseCollision temporary for a body?

Post by donggas90 »

dern23 wrote:To disable one object in the broadphase at runtime, the way to do it without modifying the API is to first clear any broadphase pairs containing the body by calling btCollisionWorld::getPairCache()->removeOverlappingPairsContainingProxy(btBroadphaseProxy*, btDispatcher*). Then to prevent the body being adding in again during the next processCollision call, you'll need to have set a custom btOverlapFilterCallback in the pair cache; I typically derive a child class from it and override the needBroadphaseCollision method. There you can return false if the body's broadphase proxy that you wish to disable is one of the arguments passed to the overridden method.
Thanks dern23. I already known about them but had not satisfied as well.
It's a good method if not consider optimization.
removeOverlappingPairsContainingProxy() is very slow method because it have to query all of pairs and occur overheads for removing pairs.
btOverlapFilterCallback is not optimized as well. because it calling after pair generated.
In other words, it just cancel to add the pair what was already generated and AABB tested, not skip the generation and AABB test. it's very inefficient. (I got this after answer to drleviathan.)
My idea is that disabled proxies(bodies) ignore perfectly when pair generation and AABB test so we can query the proxies much faster.
Recall that, a bool operation is much faster than AABB test(at least 6 FPU operations).
Last edited by donggas90 on Tue Jun 09, 2015 1:38 pm, edited 4 times in total.
donggas90
Posts: 17
Joined: Tue May 19, 2015 10:01 am

Re: How to disable BroadPhaseCollision temporary for a body?

Post by donggas90 »

gdlk wrote:Hi!

Could you give some tips how implement that (for example what is the main method to modify)? (I had the same problem (too much objects to remove/readd to the world) and forceActivationState(DISABLE_SIMULATION) is not doing the work =( )

Thanks!!
You can reference btSimpleBroadphase to implement it.
The key method is calculateOverlappingPairs().
You have to generate broadphase pairs in this method.

Cheers.
dern23
Posts: 26
Joined: Thu Oct 04, 2012 1:58 pm

Re: How to disable BroadPhaseCollision temporary for a body?

Post by dern23 »

donggas90 wrote: Thanks dern23. I already known about them but had not satisfied as well.
It's a good method if not consider optimization.
removeOverlappingPairsContainingProxy() is very slow method because it have to query all of pairs and occur overheads for removing pairs.
btOverlapFilterCallback is not optimized as well. because it calling after pair generated.
In other words, it just cancel to add the pair what was already generated and AABB tested, not skip the generation and AABB test. it's very inefficient. (I got this after answer to drleviathan.)
My idea is that disabled proxies(bodies) ignore perfectly when pair generation and AABB test so we can query the proxies much faster.
Recall that, bit operation(mask and group; CollisionChannels) is much faster than AABB test(at least 6 FPU operations).
Hi donggas90, yes I see what you're saying now about the execution flow. It is indeed inefficient to perform the AABB calculation before you know if it's even necessary! The broadphase is not a bottleneck in my application so I never put much thought into it, but your approach is clearly the way to go if you are concerned about broadphase performance. I'm just curious how you avoid looping over existing pairs (as in processAllOverlappingPairs) to disable an object that is already in collision, while the simulation is running; I guess for the btHashedOverlappingPairCache you could replace the loop (line 383-396 in btOverlappingPairCache.cpp) with a hash table lookup, but if you have a more elegant solution that could apply generally to all pair caches I'd love to be pointed in that direction!
donggas90
Posts: 17
Joined: Tue May 19, 2015 10:01 am

Re: How to disable BroadPhaseCollision temporary for a body?

Post by donggas90 »

dern23 wrote: I'm just curious how you avoid looping over existing pairs (as in processAllOverlappingPairs) to disable an object that is already in collision, while the simulation is running; I guess for the btHashedOverlappingPairCache you could replace the loop (line 383-396 in btOverlappingPairCache.cpp) with a hash table lookup, but if you have a more elegant solution that could apply generally to all pair caches I'd love to be pointed in that direction!
My answer is simple, I created my own PairCache as well. :lol:
Removed filter callback and needless features to make lighter.
but it wasn't problem because broadphase what reference my PairCache had created by me as well.
My PairCach is based on hash. but PairCache's interface is not prefectly fit into HashTable, therefore used 2 arrays instead.
One is a pairs list which is the output for dynamic world and another one is a hashes list for fast searching.
BTW, the PairCache is not a big deal, the querying of Proxies is important.
Thus my focus is to reduce count of proxies what need querying and AABB test.
Namely, I said before, if early exclude some proxies by just a bool operation from querying and AABB test, we can save much cost. (I had mistaken bit operation for bool operation in before reply.)
Therefore I have remodeled broadphase to apply early exclusion. :wink:
Post Reply