performance question

gjaegy
Posts: 178
Joined: Fri Apr 18, 2008 2:20 pm

performance question

Post by gjaegy »

Hi guys,

I decided to create a new topic, as the subject has changed compared to my previous post.

I have successfully integrated Bullet into our engine (or actually, started to ;) It is amazing how easy it is, and how realist the result is !! very good job !

However, I am not sure which collision shapes I should use to maximize performances.

So basically, I have two types of objects:
1 - the airport, static. This model is composed of many sub-objects (tower, buildings, trees, ground, etc...), I can collapsed them for the physic mesh
2 - the aircrafts / vehicles, which are composed by 3-10 sub-objects which I can collapse as well.

For 1, I think the best approach would be to use btBvhTriangleMeshShape with mass=0.
However, I am not sure how Bullet handles the shape. I know it uses a tree internally, so I guess the best thing would be to collapse all the objects, and provide bullets with one single list of vertices and one single list of indices for all the sub-objects. Am I right, or should I rather create one shape per object (so one per building, etc...) ? Or rather use a combinaison of convex shapes (using the convex decomposition sample) ?

For 2, I am not sure which is the fastest method. Should I create one concave triangle mesh shape and use GImpact ? Or would it be more efficient to use a combinaison of convex hull shapes (using decomposition as well) ? I have no idea how both approach would perform (performance-wise and quality-wise), so any input would be welcome !!


Other question, should I call the following methods ? If I should, should I do it with all different shape types ? From what I understand it would allow to skip continuous physic computations if objects are isolated enough, right ?
Code:
// Only do CCD if motion in one timestep (1.f/60.f) exceeds CUBE_HALF_EXTENTS
// _vSize is the size of the bounding box
gjFloat fMinSize = gjMin(gjMin(_vSize.x, _vSize.y), _vSize.z);
m_pBody->setCcdSquareMotionThreshold(0.5f * fMinSize);

//Experimental: better estimation of CCD Time of Impact:
m_pBody->setCcdSweptSphereRadius(0.2f * fMinSize);


Thanks a lot.

Gregory
AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Re: performance question

Post by AlexSilverman »

Gregory,

1 - You're right. The usefulness of the tree is maximized by putting as many static objects in it as possible, so you'd see the most performance gains by collapsing as much of your static environment into the same mesh as possible.

2 - I assume, since you're looking at GImpact, that these objects are going to be moving. Are they going to be controlled dynamically (as in the Bullet Vehicle demo), or are they going to be animated externally and the physics shape will just be repositioned to match the graphics mesh, or do they just need to be knocked around, but not moved as though they were real vehicles (eg. drive around)? If they are to be moving dynamically, and modeled as such, then for the vehicles you'd be best off using the vehicle shape, as in the demo. If they're going to be animated, then you have a few options. If you need accurate collision detection, you can use a kinematic mesh (You can see an example of kinematic object in the CCD Physics Demo). If not, then you can get better performance by using a compound mesh for a somewhat simple approximation of the object, made up of primitives. If they just need to be knocked around, then GImpact is fine if you need accurate collision detection. If not, then a compound mesh will work well also, and probably with better performance, but that will probably depend on the specifics of the shape you're trying to model.

As for the CCD stuff you mentioned, I may be wrong, but I don't believe that those options are enabled currently. The ContinuousDynamicsWorld is still under construction, and I believe those options are for use in it and don't affect anything in any other dynamics world.

Hope this helps.

- Alex
gjaegy
Posts: 178
Joined: Fri Apr 18, 2008 2:20 pm

Re: performance question

Post by gjaegy »

Hi Alex. First, thanks a lot for your answer.

The aircrafts are moving. Actually, my situation is a bit difficult, let me try to explain:

- basically the aircrafts are controlled by a external simulator, which sends key frames for each aircraft every second via network. Until now, on my side (3D) I was interpolating between those keyframes and updating the position of the graphic meshes each frame

- now we need to detect collisions, so I decided to use Bullet

- when a collision is detected, two options are possible:
- the reaction will be ignored and the position input sent by the simulator will continue to be used
- the input of the simulator will be ignored and the position of the model will be the one computed by bullet

So, I am not sure how to proceed and which object types I should use.

First, is it possible to update the position of the aircrafts using my interpolation scheme without polluating the physic simulation (bullet) ? How should I proceed, by updating the velocity each frame ?

Then, second issue, I don't know how to switch on/off collision response. I guess by enabling/disabling the rigid body associated with an object, is that possible ? But in the case I disabled the rigid body, how can I know when a collision occured ?

Lots of question, I am really new to the physic engine world ;) Any help would be very appreciated !

Thanks,
Gregory
AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Re: performance question

Post by AlexSilverman »

Hi,

Can anyone say if it's possible to switch an object back and forth from being dynamic to being static/kinematic? I've never tried this, but it seems as though this would do well for this situation, if it's possible.

You can initially create the plane as a kinematic object, and simply update the position/orientation of it based on the external simulator. Kinematic objects are moving static objects that influence other objects, but are not influenced by them (like a moving platform for instance). This way you wouldn't need to worry about the Bullet simulation. This would work for everything but the second type of collisions you mention (where Bullet takes over and your external simulator is ignored). For those, you could switch the plane to being a dynamic shape (GImpact or compound). Alternatively, if you're not able to make objects dynamic or kinematic on the fly, you could simply create one dynamic object and one kinematic object, and replace the kinematic one with the dynamic one (position/orientation/adding and removing from the simulation) and vice versa, whenever necessary.

As far as disabling collision response for some objects, you can override the dispatcher needsResponse method to filter out collision response for certain objects. There are some more details in this thread.

Hope this helps.

- Alex
gjaegy
Posts: 178
Joined: Fri Apr 18, 2008 2:20 pm

Re: performance question

Post by gjaegy »

Thanks a lot for your answer Alex.

I have read the thread you mentioned, very interesting. I was wondering, couldn't I switch on/off collision response (and thus dynamics) by simply doing the same thing as jackyskelyton ?

Do I really have to use kinematic objects or can I model my aircrafts using a single rigid body per model, where I disable collision response when needed ? The only issue I see is how to update the position/orientation of such an object each frame (maybe using the setLinearVelocity() each frame) ?
AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Re: performance question

Post by AlexSilverman »

Yes, you can use the same method jackskelyton uses. I'm doing this as well and it works fine. I only suggested using a kinematic object to avoid the need to manually manage the object each frame. Also, Bullet will automatically handle setting the velocity of kinematic objects based on how far the kinematic object has moved in a timestep, so collisions will be more accurate than they would if you were trying to manage this yourself.

That said however, you shouldn't have any major problems using a regular dynamic object and just explicitly controlling it each frame.

- Alex
gjaegy
Posts: 178
Joined: Fri Apr 18, 2008 2:20 pm

Re: performance question

Post by gjaegy »

OK, so the solution you think is the best is the following (just to be sure I understood correctly ;)) :

- for each aircraft create a rigid body and a kinematix object
- when a collision occures, two cases:
--- if I want the simulator to continue to control the aircraft, do nothing
--- if I want Bullet to control the aircraft:
------- remove kinematic object from world
------- initialize rigid body, and add rigid body to world

Is that right ?

I have two remaining questions:
- what do I have to initialize when I add the rigid body ? I guess position, orientation, velocity, torque. Something else ?
- when can I remove the kinematic object and add the rigib body instead ? In the dispatcher needsResponse ? Or maybe it is too late, I need to replace them before a colision occures ?

Thanks a lot and sorry for my stupid questions ;)

Greg
gjaegy
Posts: 178
Joined: Fri Apr 18, 2008 2:20 pm

Re: performance question

Post by gjaegy »

OK, I have tried to implement what you said.

It seems I can use one single rigid body, which initially has his kinematic flag enabled.

This seems to work so far. Once I want bullet to take over control on my object, I call SetKinematicState(false) (see below).

Bullet successfully takes control over the object, however, the object doesn't have any mass defined internally, and thus no gravity as well. How can I switch properly from a kinematic state to a normal state (I am currently using convex hull FYI, but that shouldn't matter) ? What am I missing ?

thanks a lot !

Code: Select all

void gjPhysicObject::SetKinematicState( gjBool _bKinematic )
{
	if (m_pBody)
	{
		gjInt iFlag = m_pBody->getCollisionFlags();
		if (_bKinematic)
		{
			iFlag |= btCollisionObject::CF_KINEMATIC_OBJECT;
			m_pBody->setActivationState(DISABLE_DEACTIVATION);
		}
		else
		{
			iFlag &= ~(btCollisionObject::CF_KINEMATIC_OBJECT);
			m_pBody->forceActivationState(ACTIVE_TAG);
		}
		m_pBody->setCollisionFlags(iFlag);
	}
}
gjaegy
Posts: 178
Joined: Fri Apr 18, 2008 2:20 pm

Re: performance question

Post by gjaegy »

I have one last issue with that solution: when aircrafts are controlled by the simulator, kinematics objects are used. However, Bullet doesn't seem to check collisions between static and kinematic objects.

needResponse() doesn't get called...
gjaegy
Posts: 178
Joined: Fri Apr 18, 2008 2:20 pm

Re: performance question

Post by gjaegy »

I have tried to override the overlapfiltercallback in order not to filter out collisions between static and kinematic objects. It seems however the CPU usage has increased significantly (20% => 30%), even with only one very simple static mesh and one aircraft (compound hull).

This is the code I use:

Code: Select all

struct myOverlapFilterCallback : public btOverlapFilterCallback
{
	myOverlapFilterCallback () : btOverlapFilterCallback() {}

	virtual ~myOverlapFilterCallback ()	{}

	// return true when pairs need collision
	virtual bool   needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
	{
		return gjTRUE;
	}
};
and then:

Code: Select all

m_pDynamicWorld->getPairCache()->setOverlapFilterCallback(new myOverlapFilterCallback ());
Is that a correct method ? Could there be any side effect ?

Thanks.
gjaegy
Posts: 178
Joined: Fri Apr 18, 2008 2:20 pm

Re: performance question

Post by gjaegy »

help... :(
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: performance question

Post by Erwin Coumans »

How many child shapes does the compound shape have?

There is currently no acceleration structure used for complex compounds, but that can be added if necessary.
Thanks,
Erwin
gjaegy
Posts: 178
Joined: Fri Apr 18, 2008 2:20 pm

Re: performance question

Post by gjaegy »

First thanks for your answer Erwin; I was really lost and appreciate therefore your support.

So it seems the way I disable the filters is OK ?

To create the compound shape I use exactly the same parameters values that are used in the demo:

m_nDecompMaxDepth = 5;
m_nDecompMaxVertices = 16;
m_nDecompConcavityPercent = 5;
m_nDecompVolumeConservationPercent = 15;

This leads to about 26 child shapes for a typical model. Maybe that is too much ?

I also disable deactivation for the kinematic rigid bodies, as seen in the Bullet samples ( m_pBodyKinematic->setActivationState(DISABLE_DEACTIVATION); ), couldn't that explain also the performance loss ? In a typical scenario about 40% of the aircrafts are immobile on park stands. How could I benefit from that situation ? Maybe enabling them when the move is higher than a threshold will do the job, i will give it a try.

Thanks a lot Erwin !