Following the poll, buoyancy seemed to be the popular choice for Box2D feature. I decided against the fancy and probably unreliable technique I was going to use, and have produced a “controller” based on good old, geometry, cribbing a fair amount of Erin Catto’s notes on the subject. Demo

To use, you need to patch Box2DAS3, and also use the separate package. Box2D seems to take the view that force effects like buoyancy aren’t a real part of the engine, so I’ve separated it.

This was the second time I’ve found a bug in Box2DAS3, just a trivial inlining of a funciton done wrong. But I guess it shows no one was actually using these features (GetVelocityAtPoint in this case), until I came along. Hopefully this contributed code makes everything easier to use.


This is the base class for controllers that provide forces to bodies. At the moment, only one is implemented.

This controller provides the forces for the buoyancy and drag of a fluid filling a half plane.
Create a new b2BuoyancyController, and add bodies to it with AddBody. Set normal and offset to specify the surface of the fluid, and fill in the various other parameters with it’s physical behaviour. As usual, code has commenting for the details.

Then call b2BuoyancyController::Step once per world step, passing the timestep.

Note: You should add and remove bodies from the controller as appropriate; for large worlds it would not be efficient to add every body to the contoller. However, do not use a sensor to detect the very wide surface, this can hurt performance. Instead, you should use several smaller sensors, or b2World::Query


I’ve fudged some of the drag calculations, but there’s honestly no good way to do it.

Coming Features

I’ll port this to C++. And I might add some more controllers to the same framework. And I suppose the buoyancy controller deserves it’s own mini-broadphase.


Box2DAS3 v2.0.1 – Buoyancy