Problem with animation sim speed and tunneling

jackjohnson
Posts: 8
Joined: Tue Sep 23, 2008 10:07 am

Problem with animation sim speed and tunneling

Post by jackjohnson »

Hi Erwin,

I'm banging my head against a wall.

I'm using a 3d graphics engine that is calling the following inside of its own render loop:

Code: Select all

void sio2PhysicRender( SIO2physic *_SIO2physic,
					  SIO2window *_SIO2window )
{
	if( _SIO2physic->state == SIO2_PHYSIC_PLAY )
	{ _SIO2physic->_btDiscreteDynamicsWorld->stepSimulation( (btScalar)( 1.0f / _SIO2window->fps ), 0 ); }
}
the stepSimulation looks like this in the header:

Code: Select all

virtual int	stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.));
and this in the .cpp:

Code: Select all

int	btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep)
{
	startProfiling(timeStep);

	BT_PROFILE("stepSimulation");

	int numSimulationSubSteps = 0;
	
	//NSLog(@"maxSubSteps=%i", maxSubSteps);

	if (maxSubSteps)
	{
		//fixed timestep with interpolation
		m_localTime += timeStep;
		if (m_localTime >= fixedTimeStep)
		{
			numSimulationSubSteps = int( m_localTime / fixedTimeStep);
			m_localTime -= numSimulationSubSteps * fixedTimeStep;
		}
	} else
	{
		//variable timestep
		fixedTimeStep = timeStep;
		m_localTime = timeStep;
		if (btFuzzyZero(timeStep))
		{
			numSimulationSubSteps = 0;
			maxSubSteps = 0;
		} else
		{
			numSimulationSubSteps = 1;
			maxSubSteps = 1;
		}
	}

	//process some debugging flags
	if (getDebugDrawer())
	{
		gDisableDeactivation = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0;
	}
	if (numSimulationSubSteps)
	{

		saveKinematicState(fixedTimeStep);

		applyGravity();

		//clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
		int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps)? maxSubSteps : numSimulationSubSteps;

		for (int i=0;i<clampedSimulationSteps;i++)
		{
			internalSingleStepSimulation(fixedTimeStep);
			synchronizeMotionStates();
		}

	} 

	synchronizeMotionStates();

	clearForces();

#ifndef BT_NO_PROFILE
	CProfileManager::Increment_Frame_Counter();
#endif //BT_NO_PROFILE
	
	return numSimulationSubSteps;
}
My iPhone view is being drawn 1/60.

Now, my problem begins when I log the 3D engine's frameRate. It struggles to get up to 10+fps, but then occasionally spikes up around 30, and also drags down to 4+fps when a dynamic icosphere collides with a static triangle mesh.

In my 3d world I have about 14 static triangle shapes with (right now) about 250 faces. Meaning, I have a large amount of faces (~15000).

I cannot get the animation of the ball flying towards the static triangle mesh targets (they are CONCAVE perhaps there's a better shape and memory solution?) at the right "speed"....

The thing drags, lags, speeds up, slows down....

Is this a function of the 3d engine or with the specific stepSimulation numbers with bullet?

I kind of dove into this head first, so any thoughts/ideas/suggestions on how to "optimize" this thing would be greatly appreciated...
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Problem with animation sim speed and tunneling

Post by Erwin Coumans »

Using 0 as second argument is not supported. I assume you didn't modify Bullet internal 'stepSimulation' implementation.

Please use a low value, like 1 or 2.

Code: Select all

stepSimulation(deltaTime,2);
You still have to determine why the simulation slows down. Are you using btBvhTriangleMeshShape?

Thanks,
Erwin
jackjohnson
Posts: 8
Joined: Tue Sep 23, 2008 10:07 am

Re: Problem with animation sim speed and tunneling

Post by jackjohnson »

Yes, for triangleMesh collision shape. Here is the construction code:

Code: Select all

case SIO2_PHYSIC_TRIANGLEMESH:
			{
				unsigned int j,
							 tri_cnt = 0;
			
				btVector3 tri[ 3 ];
				
				_btTriangleMesh = new btTriangleMesh();


				while( i != tmp->n_vertexgroup )
				{
					unsigned int n_ind = tmp->_SIO2vertexgroup[ i ]->n_ind >> 1;

					j = 0;
					while( j != n_ind )
					{
						memcpy( &v[ 0 ], &tmp->buf[ tmp->_SIO2vertexgroup[ i ]->ind[ j ] * 12 ], 12 );
						
						tri[ tri_cnt ][ 0 ] = SIO2_FIXED_TO_FLOAT( v[ 0 ] ) * _SIO2object->scl->x;
						tri[ tri_cnt ][ 1 ] = SIO2_FIXED_TO_FLOAT( v[ 1 ] ) * _SIO2object->scl->y;
						tri[ tri_cnt ][ 2 ] = SIO2_FIXED_TO_FLOAT( v[ 2 ] ) * _SIO2object->scl->z;
						
						++tri_cnt;
						
						if( tri_cnt == 3 )
						{
							_btTriangleMesh->addTriangle( tri[ 0 ],
														  tri[ 1 ],
														  tri[ 2 ] );
							tri_cnt = 0;
						}					
					
						++j;
					}
				
					++i;
				}
				
				_btCollisionShape = new btBvhTriangleMeshShape( _btTriangleMesh, 1 );
				
				break;
			}
I have been unable to determine what causes the drastic drop in framerate when the physics is first played (accompanied by setLinearVelocity(x,y,z))....

Then I notice on the sphere's return downward from its arc toward the ground, the framerate jumps back up and it smoothly falls to the ground surface....

The game engine's lead developer has told me that the physics calculations are heavy and perhaps a solution would be to perform the calculations in the stepSimulation in a different thread....

It has to be possible to play a smooth physics simulation in a 3D world with less than 6,000 faces...

Any ideas?

What is the best/easiest way or checklist of factors that would determine the perceived "speed" the ball/animation is moving? Sorry if this seems like a basic question, but I'm afraid I've submersed myself so deep I might have lost some of the basics (in plain speak)....

Thanks!