Jittery scene elements in Pool/Billiards simulation.

pjohalloran
Posts: 6
Joined: Thu Feb 17, 2011 6:54 pm

Jittery scene elements in Pool/Billiards simulation.

Post by pjohalloran »

Hi,

My first post so first of all big thanks to all those involved in the development of this fantastic library. I'm a newbie to physics so i'll try not to make any assumptions below...

I am using Bullet for collision detection and rigid body dynamics in a pool/billiards game demo I am working on. I am seeing some jitter with the pool balls when they are awake in the physics simulation. Please see the attached video link: http://www.youtube.com/watch?v=LgDj2MjVgoA

At 22 - 32 seconds of the video when the player is lining up and taking their second shot the other balls near the cue and the white cue ball are jittering up and down. Its as if the balls start falling due to gravity and then the simulation realizes they are on a shape and corrects their positions back up.

Here is how I have set up Bullet:

- Using btDbvtBroadphase, and btDiscreteDynamicsWorld.

- Every frame I am stepping the simulation like:

Code: Select all

m_dynamicsWorld->stepSimulation(deltaSeconds, 4);
My game runs at between 30 - 60 fps. The frame rate can vary a bit at times, especially on application startup (however i don't think this has anything to do with the jitter as the jitter happens constantly no matter what the frame rate).

Here is part of my bullet internal tick callback where I look for pairs of objects either colliding or seperating. Its pretty standerd. I introduced a test to ensure objects are physically colliding by ensuring i generate collision events only when the number of manifolds is greater than 0. Before i introduced this the pool balls would report a collision when their aabbs collided.

Code: Select all

		BulletPhysics * const bulletPhysics = static_cast<BulletPhysics*>(world->getWorldUserInfo());
		CollisionPairs currentTickCollisionPairs;
		
		btDispatcher * const dispatcher = world->getDispatcher();
		for(int manifoldIdx = 0, numManifolds = dispatcher->getNumManifolds(); manifoldIdx < numManifolds; ++manifoldIdx)
		{
			btPersistentManifold const * const manifold = dispatcher->getManifoldByIndexInternal(manifoldIdx);
			if(!manifold)
			{
				SafeGameLogAndPrefix(g_appPtr->GetLoggerPtr(),\
										GameLog::ERR,\
										std::string("BulletPhysics::BulletInternalTickCallback()"),\
										std::string("Failed to get the manifold pointer"));
				return;
			}

			if(manifold->getNumContacts() > 0)
			{
				btRigidBody const * const body0 = static_cast<btRigidBody const *>(manifold->getBody0());
				btRigidBody const * const body1 = static_cast<btRigidBody const *>(manifold->getBody1());
				
				bool const swapped = body0 > body1;
				btRigidBody const * const sortedBodyA = (swapped ? body1 : body0);
				btRigidBody const * const sortedBodyB = (swapped ? body0 : body1);
				
				CollisionPair const thisPair = std::make_pair(sortedBodyA, sortedBodyB);
				currentTickCollisionPairs.insert(thisPair);
				
				if(bulletPhysics->m_previousTickCollisionPairs.find(thisPair) == bulletPhysics->m_previousTickCollisionPairs.end())
				{
					bulletPhysics->SendCollisionPairAddEvent(manifold, body0, body1);
				}
			}
		}
My pool table is a btCompoundShape made of of box shapes for the table walls and the floor. There are 11 box shapes making up the pool table.

The balls are sphere shapes. The cue is a cylinder shape.

The cue and the cue ball are part of the same collision group so that the cue only affects the cue ball. The cue is a kinematic object. Previously I was taking a shot by moving the cue into the cue ball but i did not get the desired effects. Now instead I am applying an impulse onto the cue ball to take a shot.

The table and ball have the parameters:
INIT_POOLBALL_PHYSICS_INFORMATION =
{
Restitution = 0.75,
Friction = 0.5,
Density = 1.95,
LinearDamping = 0.45,
AngularDamping = 0.5
};

INIT_POOLTABLE_PHYSICS_INFORMATION =
{
Restitution = 0.5,
Friction = 0.5,
Density = 0.0,
LinearDamping = 0.0,
AngularDamping = 0.0
};

Any ideas on what i could do to correct this jitter issue?

Thanks for reading.
Paril
Posts: 18
Joined: Tue Feb 22, 2011 4:14 am

Re: Jittery scene elements in Pool/Billiards simulation.

Post by Paril »

I had this issue with a completely unrelated project, and it turned out it was the way I was drawing the spheres.

Can you reproduce the same issue by using only the debug drawer?

Are they sleeping at all (debug draw render would really help here)? Does the jitter wake them up?

A jumping framerate shouldn't, in theory, cause this to happen, since Bullet's internal tick kind of makes everything good; however, the default internal tick time is 60 fps; you say that your framerate is between 30 and 60, you may want to set the third argument of stepSimulation to 1.0f/30.0f just as a precaution (I did this in my game which runs at a fixed 30 fps). This probably isn't your issue, as what this would do in practice if it does go below 30 fps is just look slow motion, but it's just something to consider.

On an unrelated note, the physics should really be asynchronous to the rendering; this makes problems like this easier to spot.

-P
pjohalloran
Posts: 6
Joined: Thu Feb 17, 2011 6:54 pm

Re: Jittery scene elements in Pool/Billiards simulation.

Post by pjohalloran »

@Paril

Thanks for the reply. The same issue is occurring if i render the scene with the debug drawer. It only happens when the spheres are light blue. This means the balls are being included in the broadphase, right? Green means asleep. They never jitter then. Light blue means in the same broadphase area and white means the object is moving (i think). Jitter occurs in both those modes. I can post a video for you tomorrow at work if you would like to see debug drawing only.
Paril
Posts: 18
Joined: Tue Feb 22, 2011 4:14 am

Re: Jittery scene elements in Pool/Billiards simulation.

Post by Paril »

Yeah, I believe cyan means another object stepped into its island (or broadphase area, whatever it's called in Bullet) and activated it. White means it's moving from a velocity I believe.

Did you try the 1/30.0f addition I suggested?

Aside from that I don't know what the problem might be. Could you try replacing the convex shapes with primitives?

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

Re: Jittery scene elements in Pool/Billiards simulation.

Post by Erwin Coumans »

Can you share a .bullet file attached to this issue, so we can try to reproduce it?

Code: Select all

	btDefaultSerializer*	serializer = new btDefaultSerializer();
	dynamicsWorld->serialize(serializer);
 
	FILE* file = fopen("testFile.bullet","wb");
	fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1, file);
	fclose(file);
Thanks,
Erwin
pjohalloran
Posts: 6
Joined: Thu Feb 17, 2011 6:54 pm

Re: Jittery scene elements in Pool/Billiards simulation.

Post by pjohalloran »

@Paril

I tried out your suggestion for the third parameter for stepSimulation(). During my game loop I update the physics, render a frame and poll for player input. My loop runs at between 52-58 frames per second. Occasionally it might drop 10 fps or so for a time. This is resulting in:
1) Missed collisions and tunneling happens quite often.
2) The scene elements appear to jitter.

I tried out 1/30 and the problems got worse. I then tried out passing in 1/120 and 1/90 as the fixed timestep and the game ran perfectly with no tunneling and very little jitter. It felt like it was in slow motion though (Nice effect for action replays). I guess I am misunderstanding how stepSimulation works. Also, I need to decouple the physics simulation from the rendering in my main loop as per your suggestion.

If i follow these articles it should correct the issues (?):
http://bulletphysics.org/mediawiki-1.5. ... _the_World
http://bulletphysics.org/mediawiki-1.5. ... _Game_Loop


@Erwin Coumans

Thank you for your help also. I think I will try and work on the above first and i could upload a bullet file if the problem persists.
Paril
Posts: 18
Joined: Tue Feb 22, 2011 4:14 am

Re: Jittery scene elements in Pool/Billiards simulation.

Post by Paril »

Yeah. I do agree, it took me a VERY long time to get my timestep to work. I find it is very confusing compared to most physics engines because it has its own internal stuff and doesn't just "work" on the step you deliver to it (Box2D is the best example of this I can think of). A lot of the documentation is also very technical and seems to escape people in very simple terms (took me forever to figure out what the third argument actually was).

I had to actually modify the time passed to it and increase it by several factors, otherwise I got the slow motion you see; if I went "default" (ie how Bullet demos have it set up) I always get tunneling.

My game/physics logic runs at a fixed 30 FPS, so it was easy for me to set my simulation (I set mine to 1.0f / 60.0f for the best results; I mis-spoke earlier when I suggested to use 1.0f / 30.0f; it seems to work best if it's 2x your actual FPS).

-P
pjohalloran
Posts: 6
Joined: Thu Feb 17, 2011 6:54 pm

Re: Jittery scene elements in Pool/Billiards simulation.

Post by pjohalloran »

I have been searching through other posts and I found this very useful one:
http://www.bulletphysics.org/Bullet/php ... wtopic.php

That post seems to point towards a scaling problem of my game objects (my pool balls have a radius of 0.025 units, I am using the Bullet default units of measurement). It recommends to either scale up the world or to tweak the fixed time step and/or the gravity for the simulation.

To alleviate the slow motion problem I am seeing in the game now I tried out passing the following to stepSimulation:

Code: Select all

m_dynamicsWorld->stepSimulation(deltaTime*2.0f, 4, 1.0f/120.0f);
The game runs perfectly with these settings. The problem is I don't fully understand why this helps or the effects of what i did on the CPU time for physics.
  • - Does using a fixed time step of 1/120 means that stepSimulation will run for approximately 1/120 seconds? If yes, does this mean the CPU budget for my simulation has just halved over the default i was using before of 1/60?
  • - When i used stepSimulation(deltaTime, 4, 1/120) the game seemed to run in slow motion. When i doubled deltaTime it runs perfectly. I had to double delta time since I was halving the fixed time step.
  • Is it a good idea regardless of decoupling the physics simulation update from the rest of the application?
Paril
Posts: 18
Joined: Tue Feb 22, 2011 4:14 am

Re: Jittery scene elements in Pool/Billiards simulation.

Post by Paril »

Yeah, I had to double (or at least increase) my time delta as well to get them to move in a good way. The other option was to increase gravity, but that caused me more tunneling.

I know world scaling is an option, but I've heard that the scaling should be kept to a default as some of Bullet's internal stuff uses it I think. My issue was strictly the timestep, once that was fixed I scaled it back down to 1:1 and it worked fine.

-P
pjohalloran
Posts: 6
Joined: Thu Feb 17, 2011 6:54 pm

Re: Jittery scene elements in Pool/Billiards simulation.

Post by pjohalloran »

Okay, I am satisfied that this problem is solved. The problem was a misunderstanding on my part about how stepSimulation is intended to be used. I have tried out passing different parameters to stepSimulation().

Number 1, deltaTime is easy, the time since the past step. The second and third parameters, numberSubSteps and fixedTime were more difficult. My game usually runs at between 52-58 fps. I have been working on optimizing it so now the frame rate is more consistent. It used to drop 10-15 fps or so when all the rigid bodies were cyan, passing the broadphase for potential collisions. My application was at fault there though, not the bullet library! I had a few silly render operations being repeated every frame. I fixed those problems and the frame rate is more stable.

I tried out running the physics simulation with different fixedTime values (60, 120, 180 and 240 HZ) with a numberSubSteps of 12. The jitter improved with decreasing fixedTime values and is gone for 240 Hz. The CPU load increases when you pass a smaller fixed timestep to stepSimulation(). At 240 Hz, the CPU load averages at 25% of a core for my application when the cue ball rigid body only is awake. This raises to between 50-60% core utilization when all 15 ball rigid bodies are awake. In comparison, for a fixedStep of 60Hz, the CPU load is 10-15% when 1 rigid body is awake, raising to 30-40% when all 15 rigid bodies are awake.
Melinda23
Posts: 1
Joined: Mon Aug 22, 2011 8:25 am

Re: Jittery scene elements in Pool/Billiards simulation.

Post by Melinda23 »

But there is a huge problem with this approach . The problem is that the behavior of your physics simulation depends on the delta time you pass in. The effect could be subtle as your game having a slightly different “feel” depending on framerate or it could be as extreme as your spring simulation exploding to infinity, fast moving objects tunneling through walls and the player falling through the floor!
One thing is for certain though and that is that it’s utterly unrealistic to just expect your simulation to correctly handle *any* delta time passed into it. To understand why, consider what would happen if you passed in 1/10th of a second as delta time? How about one second? 10 seconds? 100? Eventually you’ll find a breaking point.
pjohalloran
Posts: 6
Joined: Thu Feb 17, 2011 6:54 pm

Re: Jittery scene elements in Pool/Billiards simulation.

Post by pjohalloran »

Yeah I agree. Its not correct to just assume the simulation will handle any delta time.

It does handle slight variations in delta time though by interpolation and the fixed time stamp parameter, right?
mi076
Posts: 144
Joined: Fri Aug 01, 2008 6:36 am
Location: Bonn, Germany

Re: Jittery scene elements in Pool/Billiards simulation.

Post by mi076 »

But there is a huge problem with this approach . The problem is that the behavior of your physics simulation depends on the delta time you pass in. The effect could be subtle as your game having a slightly different “feel” depending on framerate or it could be as extreme as your spring simulation exploding to infinity, fast moving objects tunneling through walls and the player falling through the floor!
One thing is for certain though and that is that it’s utterly unrealistic to just expect your simulation to correctly handle *any* delta time passed into it. To understand why, consider what would happen if you passed in 1/10th of a second as delta time? How about one second? 10 seconds? 100? Eventually you’ll find a breaking point.
:? The step function works fine and provides a good way to decouple framerates... If your application's rate is faster as simulation rate - there will be interpolations, if you slower, Bullet will do up to max substeps... Of course there is point of failure somewhere.... Step function returns a number... it can be bigger as max substeps value, it means the simulation steps are dropped.. and timing will visually slow down, is it a signal you have to adjust something... physics rate or max substeps or whatever else... Of course you can with parameters of this function whatever you want, it depends on many factors, but there is huge problem?