bullet3 icon indicating copy to clipboard operation
bullet3 copied to clipboard

fix AABB and inertia calculations

Open Dadido3 opened this issue 5 years ago • 14 comments
trafficstars

This changes how the AABBs and the inertia is calculated for:

  • btConeShape
  • btConvexInternalShape
  • btPolyhedralConvexShape

If i'm not wrong, the margin is added twice for inertia calculation.

Even though the inertia is approximated by the bounding box and not expected to be exact for either a cone or an arbitrary convex object, it is really noticable that small objects move wrongly. (E.g. when coins hit the ground they hardly start to rotate)

I haven't checked the inertia of other shapes, but from testing the physics in Blender they seem to look right.

Dadido3 avatar Mar 30 '20 19:03 Dadido3

Are there any problems with this merge request? Is there anything that needs to be improved before it can be merged?

Dadido3 avatar May 22 '20 13:05 Dadido3

For dynamic rigid bodies, btConeShape should be centered at 1/3 of the height, not 1/2.

stephengold avatar May 29 '20 01:05 stephengold

The aabb needs to have the collision margin added for collision detection purposes. Typically the margin is supposed to be a very small value, so does it really impact the inertia tensor noticeably?

erwincoumans avatar Aug 31 '20 22:08 erwincoumans

For small objects, say a few centimetres it's noticable. The object falls normally, but once it hits the ground the rotational movement looks like it's in slow motion.

And that's one reason people say that you shouldn't create too small rigid body objects in blender for example. A workaround would be to scale the scene up, and use the timescale value to increase simulation speed. But for some reason it doesn't work as expected. If you scale the scene up by factor 10, and increase simulation speed by that same factor. The simulation doesn't look the same for some reason. (Which is another problem that needs to be fixed in blender or bullet)

Now to the collision margin. Let me explain the changes i did:

  • In btPolyhedralConvexAabbCachingShape when the AABB cache is calculated by recalcLocalAabb the margin is added to the bounding box. The thing is, if you query the cached AABB by calling getAabb, the margin is added again. So what i did was to remove the margin from the cached AABB.

  • The same thing happens in btConvexInternalAabbCachingShape, so same fix applies there.

  • In btPolyhedralConvexShape the method calculateLocalInertia will take the AABB (Which already contains the margin), add the margin to it again, and use that AABB to return an (approximated) box inertia. So i removed the margin there too.

  • Same thing for the btConeShape

So with this change those objects still have their margin added, but only once.

Dadido3 avatar Sep 01 '20 09:09 Dadido3

@Dadido3 just a heads up, we are planning to "solve" the scale issue by switching bullet to use doubles. This way we can simulate smaller sized objects (rings, bracelets, etc) without having to resort to scaling tricks.

From our tests in the studio, the results are quite good.

DarkDefender avatar Sep 01 '20 10:09 DarkDefender

@DarkDefender What i meant with the (time)scale issue is that a twice as fast time scale is not twice as fast for some reason. But i haven't looked much into it yet, maybe i did a mistake somewhere else.

Also as a sidenote: (In february) i updated blender to the newest bullet version here. This improved simulation stability and speed, but i haven't got to make a merge request for that yet. Also it's a rather large change, so idk if it breaks something else.

Edit: The time scale thing was my mistake, it scales correctly in my tests now.

Dadido3 avatar Sep 01 '20 10:09 Dadido3

Here is a quick comparison with and without the patch:

It seems like the ring dangles a bit more freely. Especially at the beginning of the animation. test.zip

@erwincoumans The point of this patch is that the margin is already in the AABB variables, so we remove the additional margin addition in the inertia calculation (as it would effectively add the margin twice then).

@Dadido3 We just upstreamed one of the last patches that would prevent us from using the upstream version of bullet. This patch is the last one that is still applied to our bundled version.

So when the next bullet release happens, we will probably remove the bullet library we bundle in /extern

The first part of this effort is currently under review here: https://developer.blender.org/D8762 When that is accepted, I will sync /extern bullet to upstream so it is in sync until we can unbundle it.

DarkDefender avatar Sep 01 '20 10:09 DarkDefender

Just to show the difference a bit more, here is a simulation of coins with and without patch:

Inertia-Test.zip

  • Each coin is 20 mm in diameter, and 2 mm thick.
  • The bronze colored coins have a convex hull scape of a flat circle with a margin of 1 mm.
  • The blue colored coins have cylinders shapes with an embedded margin of 1 mm.

So both coins have about the same collision shape. The bronze ones have a bit larger radius because i haven't reduced it by the margin, but that doesn't matter.

Without the patch the difference between both collision shapes is huge.

Dadido3 avatar Sep 01 '20 14:09 Dadido3

With 1mm margins, a 2-mm btConvexHullShape is actually 4 mm thick, since the margin is external to the hull. For btCylinderShape, the margin is internal to the cylinder. Excessive margin distorts a btCylinderShape, but not in the same way as a hull shape. They're very different shapes, and it's not surprising they behave differently.

stephengold avatar Sep 01 '20 17:09 stephengold

@stephengold The collision shape is actually a flat disc/circle (no thickness) with a margin of 1 mm. The coin model you see in the video isn't the rigid body, it's just parented to the rigid body.

The shapes are comparable (except that the diameter of the convex hull is 2 mm larger. But that's included in the calculated inertia). They have the same rounded edge, too. You can open the .blend file and check it yourself.

Dadido3 avatar Sep 01 '20 17:09 Dadido3

I am still encountering issues originating from small objects with small inertias like a cylinder radius = 1cm, height = 4cm and weight = 17g.

Did you finish moving pybullet to double precision ? Is this available using the pip installation or do I need to build with a double precision flag or something ?

tlemarec avatar Sep 08 '21 17:09 tlemarec

This issue is about small object's having a too large inertia, so enabling double precision wouldn't help.

If you have a different problem that you think can be solved by enabling double precision, look for the build flag BT_USE_DOUBLE_PRECISION.

Dadido3 avatar Sep 08 '21 17:09 Dadido3

This issue is about small object's having a too large inertia, so enabling double precision wouldn't help.

If you have a different problem that you think can be solved by enabling double precision, look for the build flag BT_USE_DOUBLE_PRECISION.

Do you mean that this cylinder has a too big inertia ? This is not what I am seeing as increasing the inertia of the object fix my problems (jitters, "explosions" and general instability)

tlemarec avatar Sep 08 '21 17:09 tlemarec

Do you mean that this cylinder has a too big inertia ? This is not what I am seeing as increasing the inertia of the object fix my problems (jitters, "explosions" and general instability)

Sorry, i didn't meant "issue" i meant pull request. This pull request is about another problem, it's not about solver instability, but about the inertia of small objects being calculated wrongly.

If you want to enable double precision, search for BT_USE_DOUBLE_PRECISION. If there are still questions or problems, i would suggest to create a GitHub issue.

Dadido3 avatar Sep 08 '21 17:09 Dadido3