bullet3
bullet3 copied to clipboard
fix AABB and inertia calculations
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.
Are there any problems with this merge request? Is there anything that needs to be improved before it can be merged?
For dynamic rigid bodies, btConeShape should be centered at 1/3 of the height, not 1/2.
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?
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
btPolyhedralConvexAabbCachingShapewhen the AABB cache is calculated byrecalcLocalAabbthe margin is added to the bounding box. The thing is, if you query the cached AABB by callinggetAabb, 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
btPolyhedralConvexShapethe methodcalculateLocalInertiawill 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 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 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.
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.
Just to show the difference a bit more, here is a simulation of coins with and without patch:
- 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.
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 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.
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 ?
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.
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)
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.