VIEW DEMO
Ingredients
- BabylonJS is a powerful library for 2D and 3D WebGL development. While it is mostly geared towards 3D Games, it also includes 2D Sprites and Particles.
- LiquidFun is a physics library based on Box2D. It has been cross-compiled to JavaScript using Emscripten.
Creating the Physics Sim
Like all physics engines, the first step for using LiquidFun is to create a World.
// Liquid Fun
Physics objects
var gravity = new b2Vec2(0, -10);
world = new b2World(gravity);
To create water and soft body physics using LiquidFun, we use Particle Groups. In the example below, we are creating a "rectangle" that will be filled with liquid particles.
// water
var shape = new b2PolygonShape();
var vertices = shape.vertices;
vertices.push(new b2Vec2(-5, -1));
vertices.push(new b2Vec2(5, -1));
vertices.push(new b2Vec2(5, -2));
vertices.push(new b2Vec2(-5, -2));
var pd = new b2ParticleGroupDef();
pd.shape = shape;
pd.color.Set(0, 0, 192, 255);
var group =
particleSystem.CreateParticleGroup(pd);
Creating a soft body (like jelly) is just as easy - we just need to set a couple of extra flags in the particle group definition:
// red jelly circle
var circle = new b2CircleShape();
circle.position.Set(-1, 8);
circle.radius = 0.5;
var pgd = new b2ParticleGroupDef();
pgd.flags = b2_elasticParticle;
pgd.groupFlags = b2_solidParticleGroup;
pgd.shape = circle;
pgd.color.Set(192, 0, 0, 255);
particleSystem.CreateParticleGroup(pgd);
Drawing using BabylonJS
There are two different types of items we need to draw in BabylonJS: particles and bodies. BabylonJS has a robust particle system which allows customization through a custom update function. Inside this custom update function, we can set the Babylon particle position and color based on the LiquidFun particle information:
// draw particle
systems
for (var i = 0, max =
world.particleSystems.length; i < max; i++) {
var
system = world.particleSystems[i];
var
particles = system.GetPositionBuffer();
var
color = system.GetColorBuffer();
var
maxParticles = particles.length;
var
transform = new b2Transform();
transform.SetIdentity();
for
(var i = 0, c = 0;
i < maxParticles && i < particlesBJS.length;
i < maxParticles && i < particlesBJS.length;
i += 2, c += 4) {
particlesBJS[i].position.x =
particles[i];
particlesBJS[i].position.y =
particles[i + 1];
particlesBJS[i].color.r =
color[c];
particlesBJS[i].color.g =
color[c + 1];
particlesBJS[i].color.b =
color[c + 2];
}
}
Drawing the other bodies, such as ground or rigid physics objects is usually dependent on what you want to show in your simulation. In the demo, we have ground objects and a little "smiley face" mesh that can be dragged around. In the case of the "smiley face," I used a cylinder with a material for the face:
var shape = BABYLON.Mesh.CreateCylinder("cylinder", 0.1, fixture.shape.radius * 2,
fixture.shape.radius * 2, 24, 1, that._scene, false);
... and then updating the position of the objects must be done on each iteration of the render loop. We need to set the position of the BabylonJS objects to be the same as the LiquidFun physics bodies:
var pos =
fixture.body.GetPosition();
var angle =
fixture.body.GetAngle();
fixture.babylonShape.position.x
= pos.x;
fixture.babylonShape.position.y
= pos.y;
Next Steps
This was just a quick overview of using BabylonJS and LiquidFun together. If you want to learn more, here are some links to get started: