Minimalist game loop with tunneling

Post Reply
avithohol
Posts: 34
Joined: Sun Feb 12, 2017 10:22 am

Minimalist game loop with tunneling

Post by avithohol »

I have created a minimalist game loop example using GL3 + GLEW + SDL2 + GLM + BulletPhysics 2.87.
See attached executable, and VisualStudio 2017 solution.
Just extract it to C drive, and run.

Video, for those who don't want to download the sample:
https://youtu.be/PIuBNMW-tbo

Could anybody help me understand, why the falling box penetrates the ground?

Where does my small example code fails?

I try to aim for a 1/60 fixed stepped, frame rate independent, and deterministic game loop as described here:
http://www.bulletphysics.org/mediawiki- ... _Game_Loop
http://www.bulletphysics.org/mediawiki- ... _The_World

Which I think its already in place.

I have read a lot about inaccuracy problems, but none of these should happen in such a small case example like this.
All these workarounds are overshoot, at least to me.

Known workarounds for tunneling:
  • Increase tessellation (make the ground smaller here):
    This mitigates the problem, but unacceptable in real scenarios, where you cannot tessellate all surfaces to 1 unit wide triangles.
  • Increase the fixed timestep resolution (3rd parameter in stepSimulation).
    1/240 value seems to solve the issue, but the cost is heavy on the CPU.
    With 1/60 values we can smoothly simulate hundreds of falling boxes, but with 1/240 only few dozens.
  • Enable CCD on the dynamic body.
    This is overshoot for simple falling body pulled by only gravity. CCD should be used only for FAST, and SMALL objects like bullets.
Is it really impossible to simulate accurately with 1/60 timestep, a 1m wide box, falling down on btBvhTriangleMeshShape static ground?
Or is there a fundamental problem with my implementation?

Any help on the topic is greatly appreciated.

Thank you!

P.S.:
Here are some debate how 1/60 should be more than enough for a simulation like this:
https://www.gamedev.net/forums/topic/63 ... -timestep/



Some more clarification:

The scene is simple, and consists of only 2 objects:
1. One small dynamic box, falling down from 7 meters
2. One large static box, with btBvhTriangleMeshShape.

btBvhTriangleMeshShape was choosen for the static ground, as it is flexible to create more complex static shapes, like a simple game map, but right now it's just a thick box.

In the 'void render()' function, the MotionState is used to get interpolated transformation for the to be rendered falling box.
Attachments
GameLoopExample.zip
(3.91 MiB) Downloaded 540 times
avithohol
Posts: 34
Joined: Sun Feb 12, 2017 10:22 am

Re: Minimalist game loop with tunneling

Post by avithohol »

No replies could mean, there is nothing else can be done beside what is already outlined in the question.

Or no replies can mean i asked the question wrong :)
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Minimalist game loop with tunneling

Post by drleviathan »

From my own perspective: there isn't much new info to add:

Box is 1x1x1m and falls from 7m with downward acceleration of about 10m/sec --> time to hit ground = 1.183 seconds.

Velocity of box when it hits ground = 1.183sec * 10.0m/sec^2 = 11.83m/sec.

Distance traveled by box per 1/60th sec substep = 11.83 * (1 / 60) = 0.1972m

So the box could end up penetrating the floor by up to about 0.2m after one substep.

You're seeing it penetrate 0.1 to 0.15m.

Yep.

The good news being: Bullet's penetration resolution code successfully pushes the object back out.

If you're taking fixed substeps and using a MotionState to obtain a transform for your GameObject then maybe you're seeing the "future predicted transform" effect rather than the body's true transform. In other words:

When taking fixed substeps but supplying variable timesteps as input to btDynamicsWorld::stepSimulation() Bullet will only step forward by whole substeps and will "roll" any remainder into the next stepSimulation(). Meanwhile btDefaultMotionState::getWorldTransform() provides an extrapolated transform that uses this "remainder" to estimate a "future" transform that matches the end of the whole "step". This reduces visual aliasing when the physics substep rate and render frame rate are not exactly the same, however the "future" prediction can appear to be in penetration, even when there is no true penetration at the end of the step.

If you were to lock the simulation and render times together you'll "see" less penetration. Even though penetration occurs after the integration part the penetration resolution "handles" it and there isn't much penetration at the very end of the step. Put another way: if you ensure there is no "rollover" from your steps you should see less penetration.

As I said, this only applies if using fixed substeps and MotionStates.
hyyou
Posts: 96
Joined: Wed Mar 16, 2016 10:11 am

Re: Minimalist game loop with tunneling

Post by hyyou »

I am out of idea.

I have never faced such problem for the built-in btBoxShape.
Perhaps, it is limitation of btBvhTriangleMeshShape or its margin.
(more info about margin) https://www.youtube.com/watch?v=BGAwRKPlpCw
avithohol
Posts: 34
Joined: Sun Feb 12, 2017 10:22 am

Re: Minimalist game loop with tunneling

Post by avithohol »

Thanks for the reply.

Yep, I do use substeps, and MotionStates, giving the best results, that's what the attached code shows.

Currently my best "workaround" is to "increase" the resolution to 1/120.

drleviathan wrote: Fri Apr 27, 2018 10:50 pm From my own perspective: there isn't much new info to add:

Box is 1x1x1m and falls from 7m with downward acceleration of about 10m/sec --> time to hit ground = 1.183 seconds.

Velocity of box when it hits ground = 1.183sec * 10.0m/sec^2 = 11.83m/sec.

Distance traveled by box per 1/60th sec substep = 11.83 * (1 / 60) = 0.1972m

So the box could end up penetrating the floor by up to about 0.2m after one substep.

You're seeing it penetrate 0.1 to 0.15m.

Yep.

The good news being: Bullet's penetration resolution code successfully pushes the object back out.

If you're taking fixed substeps and using a MotionState to obtain a transform for your GameObject then maybe you're seeing the "future predicted transform" effect rather than the body's true transform. In other words:

When taking fixed substeps but supplying variable timesteps as input to btDynamicsWorld::stepSimulation() Bullet will only step forward by whole substeps and will "roll" any remainder into the next stepSimulation(). Meanwhile btDefaultMotionState::getWorldTransform() provides an extrapolated transform that uses this "remainder" to estimate a "future" transform that matches the end of the whole "step". This reduces visual aliasing when the physics substep rate and render frame rate are not exactly the same, however the "future" prediction can appear to be in penetration, even when there is no true penetration at the end of the step.

If you were to lock the simulation and render times together you'll "see" less penetration. Even though penetration occurs after the integration part the penetration resolution "handles" it and there isn't much penetration at the very end of the step. Put another way: if you ensure there is no "rollover" from your steps you should see less penetration.

As I said, this only applies if using fixed substeps and MotionStates.
avithohol
Posts: 34
Joined: Sun Feb 12, 2017 10:22 am

Re: Minimalist game loop with tunneling

Post by avithohol »

hyyou wrote: Sun Apr 29, 2018 2:18 am I am out of idea.

I have never faced such problem for the built-in btBoxShape.
Perhaps, it is limitation of btBvhTriangleMeshShape or its margin.
(more info about margin) https://www.youtube.com/watch?v=BGAwRKPlpCw
Thanks, I knew that video, and tried many margin combination.

My findings are here:
https://pybullet.org/Bullet/phpBB3/view ... =9&t=12046

Basically, with my tests (see the videos) the BoxShape is more accurate than a same sized btBvhTriangleMesh.
PcChip
Posts: 33
Joined: Sun May 20, 2018 3:09 pm

Re: Minimalist game loop with tunneling

Post by PcChip »

Hi,

I'm trying to learn Bullet and I'm having the exact same problem with Bullet-2.87 compiled with Visual Studio 2017

I've tried a simple 128x128 heightfield, and also a btBvhTriangleMeshShape. I've confirmed with Debug Draw that the physics mesh looks correct (and correctly matches my actual rendered terrain)

when dropping btSphereShapes on it, they behave perfectly

however, when dropping btBoxShape, or a btConvexHullShape onto it under gravity, approximately 5-10% of the objects fall through the terrain

my timestep is the default (1/60 I assume)
m_numterations: I've tried 1-200 with the same result

I call stepSimulation(deltaTime, 10) , and have tried all the way up to (deltaTime, 100) with no change (except in processor usage/lower FPS of course)

is this a problem with Bullet 2.87 ? should I try compiling the latest unreleased version from the github repo? should I try an older version?

Here's a video that shows the problem - you can see objects falling through in the upper right corner - https://www.youtube.com/watch?v=bvz4Ry3 ... e=youtu.be
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Minimalist game loop with tunneling

Post by drleviathan »

PcChip, you should read the original thread for advice on how to solve your problem.

BTW, the second (optional) argument to stepSimulation(timeStep, maxSubSteps, fixedTimeStep) just specifies the max number of substeps to use. The default substep duration is determined by the third (optional) argument which you are not using, so you get the default 1/60 sec substep. To take smaller substeps do something like this:

Code: Select all

stepSimulation(timeStep, 4, 1.0/120.0);
If you set your maxSubSteps to 4 then your simulation will not "loose time" as long as your timeStep are never longer than 3 substeps (this because of how Bullet will accumulate any remainder after stepping as many full substeps as possible). You can set this number larger, but it doesn't really make sense to set maxSubsteps to be really big (like 100)... unless you're expecting the simulation to not "lose time" even when your game frame rate is really really slow like 1Hz. The maxSubSteps argument is intended to prevent the "spiral of death" problem when the physics calculations get really really slow.
PcChip
Posts: 33
Joined: Sun May 20, 2018 3:09 pm

Re: Minimalist game loop with tunneling

Post by PcChip »

Hi drleviathan,

thanks for the feedback,

I actually did read that thread before making my post, but I didn't see an answer that actually fixed the OP's problem. And since I'm having the same problem, I wanted to add to the discussion in case 2.87 has a bug

it's just simple dropping of objects under gravity from a height of ~10, falling to a height of ~1, there should be no "falling through" at these speeds with normal/sane timestep values should there?

I assumed it must be a bug because btSphereShape works perfectly, however btBoxShape and btConvexHullShape both exhibit this problem

I'm open to all suggestions of what I should do, although I don't really want to enable CCD for such a simple "dropping things onto the ground" simulation due to the increased processor usage (I'm trying to target 60+ fps on midrange machines)
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Minimalist game loop with tunneling

Post by drleviathan »

Turning on CCD is not the only solution. Nevertheless, it is easy to try and it might not be as expensive as you think. The CCD proxy radius and motion threshold is is a per-RigidBody setting.

The best solution IMO would be to not use thin triangle shapes for the ground, but to build it out of convex shapes. This can be done as part of the content creation pipeline, not during runtime.
PcChip
Posts: 33
Joined: Sun May 20, 2018 3:09 pm

Re: Minimalist game loop with tunneling

Post by PcChip »

drleviathan wrote: Thu May 24, 2018 3:23 pm The best solution IMO would be to not use thin triangle shapes for the ground, but to build it out of convex shapes
so what's the point of btHeightfieldTerrainShape existing in Bullet 2.87 ?
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Minimalist game loop with tunneling

Post by drleviathan »

Dunno, I don't use it personally. I suppose it works ok for "relatively slow moving objects". Note you can achieve "relatively slow" several ways: (1) reducing substep size (2) using only slow objects in game or (3) design a game such that max velocity of object depends on its size: larger can be faster.

It may be the case that btHeightfieldTerrainShape works well for convex objects that actually use CCD (hint hint). Did you try it yet? What did you find?
avithohol
Posts: 34
Joined: Sun Feb 12, 2017 10:22 am

Re: Minimalist game loop with tunneling

Post by avithohol »

PcChip wrote: Thu May 24, 2018 12:59 am Hi drleviathan,

thanks for the feedback,

I actually did read that thread before making my post, but I didn't see an answer that actually fixed the OP's problem. And since I'm having the same problem, I wanted to add to the discussion in case 2.87 has a bug

it's just simple dropping of objects under gravity from a height of ~10, falling to a height of ~1, there should be no "falling through" at these speeds with normal/sane timestep values should there?

I assumed it must be a bug because btSphereShape works perfectly, however btBoxShape and btConvexHullShape both exhibit this problem

I'm open to all suggestions of what I should do, although I don't really want to enable CCD for such a simple "dropping things onto the ground" simulation due to the increased processor usage (I'm trying to target 60+ fps on midrange machines)
OP here. So yes, i got no magic bullet answer (no pun intended),
only confirmation on my recipes already outlined in the original question (resolution,CCD,tessaltion)

I found few useful threads answered by Erwin himself (who created this API):
https://pybullet.org/Bullet/phpBB3/viewtopic.php?t=3413
https://www.sjbaker.org/wiki/index.php? ... dom_advice

No big findings there either.
My impression about our case here, is that the triangle size is the most important factor along with simulation resolution.
In other words, make your triangle shapes even smaller, and increase the step resolution:
stepSimulation((btScalar)mPhysicsTimer.getElapsedMicroSeconds() / 1000000.0f, 10, 1.0f/120.0f);

I save CCD (per body Continous Collision Detection) for small and very fast moving objects like a missile.

This way I survive, and has a kinda stable simulation, but with higher CPU and memory cost.

Regarding the "box vs sphere" accuracy ... my very wild shoot in the dark:
I also found that static triangle shape is less accurate than the same sized box shape, see my other post:
https://pybullet.org/Bullet/phpBB3/view ... =9&t=12046

So we can say: sphere > box > trishape :)

I think it comes from the mathematical modelling,
where a sphere is just inherently more simple to model, hence more accurate.
While a box has 8 points, and edges, make the math more complex and more instable.
Even if you think about frustum culling, implementing a sphere in frustum and a cube in frustrum is wastly different,
and sphere is the most simple and precise to test against a plane.

That's my 2 cents ... i somebody comes around here and clean up this messy thread i am doing here :)
Post Reply