Wednesday, March 26, 2014

babylon.js: physics and character animation


In this post we’ll see how we can create physics-enabled environments mixed with character animation for gaming using babylon.js and WebGL.
Kick around some boxes and beach balls in the demo

In previous posts, I showed how we can use babylon.js to create 3D Maps using Bing and share 3D Scans from Kinect. But the heart of babylon.js is all about games, and here we’ll talk about aspects of interactive, physics-based 3D games using the framework.

Skeletal Animation

Skeletal animation is used to animate meshes based on bones – such as the walking character animation shown here. Babylon.js supports skeletal animation, and will accept animations exported from Blender. When creating the animation for this demo, I needed separate animations for walking, kicking, jumping and standing. What I chose to do was just append all of these separate animations into a single group of 90 frames, which you can see in the image here.

To control this animation in babylon.js, we can pass in the start frame and end frame we wish to play back:

scene.beginAnimation(_skeletonRegularGuy, 31, 60, true, 1.0);

One important note when exporting animations from Blender: we need to bake the location, rotation and scaling for the animation before export! To do this, select your mesh in Object Mode and then press Ctrl+A and choose Location. Repeat this for Rotation (and Scale if you have any key frames affecting scale).



Keyboard Input

In this demo, I used a simple means of tracking which keys were down, first by adding standard event handlers:
        // key input
        window.addEventListener("keydown", this.handleKeyDown, false);        window.addEventListener("keyup", this.handleKeyUp, false);
… and then tracking the states of each key in a simple attribute:
this.handleKeyDown = function (evt) {
keyStates[evt.keyCode] = true;
};

To make things a bit easier to track, we can add an enumeration that equates key codes to directions for our character:
var enumDirectionKeys = {
    keyNone: 0,
    keyUp: 87,
    keyLeft: 65,
    keyRight: 68,
    keyDown: 83,
    keyJump: 32
}

Virtual (Touch) Joysticks

If you happen to try the demo on a touch-enabled device, you can use the left side of the screen to control a virtual joystick for movement, and the tapping anywhere on the right side of the screen makes the character kick. This is made possible by using the virtual joystick class from the GameFX library, which is included as babylon.virtualJoystick.js in the babylon source.
We can create an instance of the joystick with:
   joystick = new BABYLON.GameFX.VirtualJoystick(true);
… and then read the delta position of the joystick like so:
   var delta = (joystick.deltaJoystickVector);

Sound

For sound support, I used create.js. It’s pretty straight forward to use the sound library portion of create – first you initialize and add a manifest:
        // sound fx
        createjs.Sound.initializeDefaultPlugins();        var audioPath = "sounds/";
        var manifest = [            { id: "kick", src: "kick.mp3" },            { id: "wood", src: "wood.mp3" },            { id: "ball", src: "ball.mp3" },        ];
 createjs.Sound.registerManifest(manifest, audioPath);
… after which you can play any file by its id:

createjs.Sound.play(
"wood");

Adding Physics

Babylon.js uses Cannon.js to support 3D Physics, and it makes it very easy to do so through imposters. For example, to add physics to our “beach balls,” we can use the SphereImposter in a call to setPhysicsState like so:

ball.setPhysicsState({ impostor: BABYLON.PhysicsEngine.SphereImpostor, mass: 0.05, friction: 0.5, restitution: 0.9 });
However, there are some advanced scenarios where a simple imposter will not do – for example, in the picture to the right you see our “dude” physics in the demo. Since we want our dude character to walk around and move/kick the physics objects around him, we need to have a more advanced imposter. In this case, we can join a “wheel sphere” to  a “body box” and then apply impulse to the wheel to move the box around. Additionally, the “kick region” is used to detect collisions with other physics objects when the character performs his kick move.
To accomplish the character physics, three physics imposters are used.

Getting Help and Support

If you choose to use babylon.js for your next project, here are some resources that can get you started.
Babylon.js forums on HTML5 Game Devs – this is an awesome community of like-minded game devs using javascript frameworks such as babylon.
Babylon.js samples and source – if there is one thing babylon provides, it’s a lot of cool samples. Poking around through this code is invaluable in learning the ropes.
Babylon.js Wiki – full of some good tutorials to get started.