Forming tall stacks

sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York

Forming tall stacks

Post by sparkprime »

When I spawn a tall stack of jenga blocks, they tend to bounce and explode:

http://www.youtube.com/watch?v=Tcai1mlDgm8

It behaves nicely when the stacks are short though:

http://www.youtube.com/watch?v=h2WpHm4Y2qc

Is it possible to minimise the effect at all? Is this behaviour typical of bullet simulations? The blocks are quite small, 0.24 units tall, 0.3 units wide, 0.9 units long. Does this affect it? Can bullet be tuned to accept smaller blocks without problems?

The collision meshes are standard bullet boxes. The floor is a large box (2 units deep, 600 by 600 units square). Jenga blocks are 0.1 units of mass. The floor is massless (static).

For those who care: OGRE is used for the graphics, lua for the scripting :)
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Forming tall stacks

Post by Erwin Coumans »

It looks like there are gaps between the boxes in your stack.

Make sure there is no gap at the start, and try replacing the ground with a btStaticPlaneShape.
There are several other ways to improve simulation quality, but with a gap nothing helps, that that has to be sorted out first.

Hope this helps,
Erwin
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York

Re: Forming tall stacks

Post by sparkprime »

I create the box with a z component of 0.12 and the boxes are spaced at 0.24, so there should be no gap. It looks like they lie into each other a bit, penetrating before being bounced back. I'll try the plane now.
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York

Re: Forming tall stacks

Post by sparkprime »

The plane didn't change much I'm afraid but I'm glad to have added it to my repertoire of game engine collision shapes which at the moment is just spheres, boxes, cylinders, and planes :) I was a bit confused at first because everything seemed to be penetrating the plane, but then I looked at the demos and saw the plane was being created with a large negative constant factor, and then brought back to zero with rigidbody positioning. So I copied that configuration and it worked fine.

I've made a new video without interpolation and with the steps spaced out in time. The physics engine is still running at 75hz but I call stepSimulation less frequently. You can see the individual steps quite clearly, and the error propogating up the stack.

http://www.youtube.com/watch?v=PfQPiLmTA14

Here is what I think is happening:

It seems that each brick immediately penetrates the one below by a tiny amount, as you would expect as it is accelerating from rest. But when you multiply this tiny penetration by the 30 layers in the stack, the vertical offset accumulated at the top is bigger than one block, causing an explosion when it "bounces back".

Decreasing the step size allows me to build bigger towers as it decreases the amount of penetration. Are there any other ways?

Unrelated note: demolishing walls is fun :)

http://www.youtube.com/watch?v=xd2vqsZLcvY
Last edited by sparkprime on Sat Jun 28, 2008 3:33 am, edited 1 time in total.
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York

Re: Forming tall stacks

Post by sparkprime »

I put the original movies (before youtube butchered their quality) here:

http://spark.woaf.net/bullet/

The codec is h264 if you need to muck about to run it.
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York

Re: Forming tall stacks

Post by sparkprime »

I should also mention that I spaced the blocks more in the non-vertical directions x & y, in case that was causing a problem.

I've tried various different z spacings too but they all do the same thing, just a bit worse (more penetration).
chunky
Posts: 145
Joined: Tue Oct 30, 2007 9:23 pm

Re: Forming tall stacks

Post by chunky »

For those who care: OGRE is used for the graphics, lua for the scripting
Heh. Me too, in my current project. Do you have a full set of lua bindings for bullet? If so, any interest in sharing it? :-D

Regarding the original problem, you might want to check that your restitution is set to zero to reduce inherent bounciness, and increase your damping a bit, just enough to slow down the blocks on their downward travel immediately after creation.

Gary (-;
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York

Re: Forming tall stacks

Post by sparkprime »

Not a full set. I wrapped the physics engine and collision shapes in an abstraction that only exports the behaviour I'm interested in, and it is this abstraction that has lua bindings. I wanted to cover my back in case I needed to change physics engines in the future.

I did play with lots of attributes, including both damping values. Thinking about it though, using damping should have helped, in particular setting a linear damping of 1 should have stopped the motion altogether. I looked at the source and noticed a few things:

In btRigidBody::applyDamping, we have:

Code: Select all

m_linearVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_linearDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
m_angularVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_angularDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
I'm not sure multiplying by the timestep is the correct thing to do here. I think it should be raised to the power of the timestep. Note when timeStep==1 the behaviour is the same, but for smaller timesteps, the quantitiy of damping still ranges from 0 to 1.

I'm currently doing this:

Code: Select all

        m_linearVelocity *= powf(GEN_clamped(1.0 - m_linearDamping, 0.0, 1.0),timeStep);
        m_angularVelocity *= powf(GEN_clamped(1.0 - m_angularDamping, 0.0, 1.0),timeStep);
Which is obviously not up to bullet's quality standards (shouldn't be powf, etc) but is the correct equation in my opinion.

Also, bullet only damps the velocity induced by forces applied to the rigid body. It does not damp velocity induced by penetrations. I'm not sure how to approach this, since applying the damping before and after collision detection would result in twice as much damping. Maybe applying the damping to only the extra velocity induced by the collisions? Or maybe reversing the damping, integrating the transforms, and then applying the damping again would work.


Anyway, with just the first change, I can damp the jenga bricks properly, but in order to have much effect I have to damp them a lot - so much that their behaviour becomes unrealistic. I cannot currently stop the explosion with damping, because the penetration impulses propogate up the stack and magnify because they are not damped. I can only damp the explosion itself. Perhaps if the penetration impulses were also damped then it would be possible to build a tall realistic stack.

Dropping the gravity to moon-levels also helps of course :)

As does a smaller time step.
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York

Re: Forming tall stacks

Post by sparkprime »

Actually thinking about it, increasing the linear damping should have reduced the amount of penetration as the stack initially settles, as the bricks would reach a smaller terminal velocity, but it seems not to have done so. Maybe because they are accelerating from rest, this effect is negligible.
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York

Re: Forming tall stacks

Post by sparkprime »

As one final experiment, I tried applying half the damping in predictUnconstraintMotion (using timestep/2) and the other half before body->predictIntegratedTransform(timeStep, predictedTrans) in integrateTransforms. This didn't seem to have any effect, though. Maybe the penetration-induced velocities are just too small.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Forming tall stacks

Post by Erwin Coumans »

The dynamic rigid body bricks are very small, so the tiny size is likely to cause instable stacking simulation. A few suggestions:
  • Can you try to make them bigger, and see if that helps?
  • A smaller _internal_ timestep might improve too (3rd argument of stepSimulation).
  • Don't use 0 as second argument of stepSimulation.
  • Try to enable split impulse and see if that improves the simulation stability:

    Code: Select all

    discreteWorld->getSolverInfo().m_splitImpulse = true;
    
Hope this helps,
Erwin
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York

Re: Forming tall stacks

Post by sparkprime »

Erwin Coumans wrote:The dynamic rigid body bricks are very small, so the tiny size is likely to cause instable stacking simulation. A few suggestions:
  • Can you try to make them bigger, and see if that helps?
How much bigger?
[*] A smaller _internal_ timestep might improve too (3rd argument of stepSimulation).
Halving the internal timestep doubles the accuracy (in terms of the height you can build before it explodes).

Obviously changing the external timestep makes no difference whatsoever.
[*] Don't use 0 as second argument of stepSimulation.
I always use a fixed timestep but I often step the simulation manually with a keypress, or I animate it slowly, to watch what's going on. I don't interpolate because that just gets in the way of seeing what is happening inside the dynamics engine. I fully understand what's going on with respect to this stuff and how to get bullet to do what I want.

[*] Try to enable split impulse and see if that improves the simulation stability:
Now this actually makes a big difference. What happens is it doesn't explode anymore, although the penetration does build up. I'll do some more tests and record some videos.
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York

Re: Forming tall stacks

Post by sparkprime »

Also, what do you think about my comments on the damping? (See the above post with code in it)
Last edited by sparkprime on Wed Jul 02, 2008 12:33 am, edited 1 time in total.
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York

Re: Forming tall stacks

Post by sparkprime »

With splitImpulse, there is still an explosion, but it is a slightly less explosive explosion. It seems I get an identical penetration / cumulative bounce back pattern going up the stack, but with splitImpulse the effect is more spread out over the stack. In some sense, the jolt is shared among more the bricks. It seems to be generally more pleasing an effect. However, there is a weird effect with the bottom brick when using splitImpulse - it gets jammed into the ground under the weight of all the others. This doesn't happen without splitImpuse. (edit: actually the jamming into the floor only happens with massive stacks)

Unfortunately I can't make videos because for some reason they keep coming out corrupted...


More importantly, I tried the simulation with blocks 10 times larger in all 3 dimensions, and it's a lot more stable. The effect is identical to making the internal stepsize smaller. Although the amount of penetration is the same, it seems that since the blocks are so much bigger, the penetration is much smaller in comparison to the block size.

How can I reconfigure bullet to give this kind of behaviour for small blocks instead of large ones? Should I scale everything in the physics world? this would be a pain and cost CPU time.

It must be possible to tweak some of the default values somewhere to reproduce this behaviour. Do you have any idea what causes it?