# Moving Objects In JavaScript 3D Physics using Ammo.js and Three.js

So, from the earlier article, we’ve seen how to setup the physics world, add objects to it and even filter collisions using masks. We equally touched on constraints (say joints).

What if you wanted move the objects around, how would you go about it? For example in a game you want your character to move while the walk animation is playing or you need a floating block that would ferry a player across a dangerous sea of lava unto a safe section of the game scene.

To be able to achieve this we'd have to revisit some fundamentals.

## Dynamic, Static and Kinematic Rigid Bodies

Quoting from bullet user manual:

There are 3 different types of objects in Bullet

Dynamic (moving) rigidbodies: positive mass, every simulation frame the dynamics will update its world transform.

Static rigidbodies: zero mass, cannot move but just collide.

Kinematic rigidbodies: zero mass, can be animated by the user, but there will be only one way interaction: dynamic objects will be pushed away but there is no influence from dynamic objects.

Heads-up: There is going to be a lot of copying and pasting if you are to follow along with this tutorial.

## Dynamic Rigid Bodies

Dynamic rigid bodies have mass greater than zero and will move around being affected by the forces and laws governing the physics world. This means they will be affected by gravity, impulse, and would respond appropriately to collisions from other bodies. To move a dynamic rigid body you either use `applyForce`, `applyImpulse `or `setLinearVelocity` . These are all rigid body methods.

`applyForce `and `applyImpulse `would result in a body acceleration, so your characters will have momentum”, but for this tutorial we will use `setLinearVelocity`.

We could be creating an example to demonstrate this. Our example will consist of a ball that will be moved around using the WASD keys.

We’ll still maintain the workspace setup used for the earlier tutorial. So once again if you haven’t gone through that tutorial please do

Go ahead and create a html file in the workspace and give it any reasonable name. Copy the below code into it as a form of bootstrapping.

If you view this in your browser you’ll see a plane with a red ball on it.

Under the variable declaration section of the code add:

`let ballObject = null, moveDirection = { left: 0, right: 0, forward: 0, back: 0 }const STATE = { DISABLE_DEACTIVATION : 4 }`

`ballObject` will be our handle to the ball and `moveDirection` will be used to hold the respective directional key (WASD) that is pressed.

Constant `STATE` is a compiler-define in the bullet source file ( btCollissionObject.h). As at the time of this writing it is yet to be included in ammo.idl, however its value gives the expected result in engine.

When a rigid body is no longer participating in dynamic interaction in the physics world, ammojs deactivates it. In this deactivated state we won’t be able to apply force to it. To stop this from happening set the activation state for the rigid body to `STATE.DISABLE_DEACTIVATION`.

Back to the code. Go to definition of `createBall` method and change the line that has:

`let ball = new THREE.Mesh(new THREE.SphereBufferGeometry(radius), new THREE.MeshPhongMaterial({color: 0xff0505}));`

to

`let ball = ballObject = new THREE.Mesh(new THREE.SphereBufferGeometry(radius), new THREE.MeshPhongMaterial({color: 0xff0505}));`

This sets the `ballObject` as a handle to the ball that we created.

We are not done yet. After the line that says `body.setRollingFriction(10);` add

`body.setActivationState( STATE.DISABLE_DEACTIVATION );`

Next is to handle `keydown` and `keyup` events for the WASD keyboard keys.

Copy and paste the below snippet after `renderFrame()` method definition:

The above wires the keyboard’s `keydown` and `keyup` events to appropriate event handlers that are also defined in the snippet.

How the event handlers work is to set a key’s `moveDirection` component to 1 when the key is pressed (`handleKeyDown()`) and to 0 when released (`handleKeyUp()`). Pretty straight forward I guess.

Lest we forget, call this newly added `setupEventHandlers()` method inside `start()` method at the top, right before the invocation of `renderFrame()`. Your `start()` method should look like :

`function start (){  tmpTrans = new Ammo.btTransform();  setupPhysicsWorld();  setupGraphics();  createBlock();  createBall();  setupEventHandlers();  renderFrame();}`

Now to actually move the ball we have to

• first resolve the directions set in `moveDirection` variable
• set a `vector` with the resolved directions
• multiply the `vector` by a scaling factor
• then apply the `vector` as the linear velocity of the balls rigid body

All these are contained in the the `moveBall()` method below. Paste it into your code after `createBall()` method definition

Note that the y component is zero because we didn’t handle up and down movement.

To `renderFrame()` method body add a call to `moveBall()` just after the line that has

`let deltaTime = clock.getDelta();`

`renderFrame()` should now look like:

`function renderFrame(){   let deltaTime = clock.getDelta();   moveBall();   updatePhysics( deltaTime );   renderer.render( scene, camera );   requestAnimationFrame( renderFrame );}`

If you followed every instruction above then your final code should look like this and on pressing the WASD keys you’ll notice that the red ball moves. Here is a working demo.

Pause for a bit of reflection.

In essence what is happening is that for each render loop we check if any directional key is pressed. If so we apply linear velocity, based on the resolution of the directional keys, to the physics rigid body. In this way our object moves.

## Static Rigid Body

Static rigid bodies, which have a mass of zero, are just what their name says . They should never be moved by the user

## Kinematic Rigid Body

Quoting from bullet user manual:

If you plan to animate or move static objects, you should flag them as kinematic. Also disable the sleeping/deactivation for them during the animation. This means Bullet (ammojs) dynamics world will get the
new worldtransform from the btMotionState every simulation frame.

kinematic objects are static objects that can be moved, but by the user. They are not affected by any force from the physics world not even gravity, they are just there. A good example of where a kinematic object would be useful, as stated earlier above, is a floating block that would ferry a player across a dangerous sea of lava unto a safe section of the game.

Since kinematic bodies are not affected by forces in the physics world it means we cannot use `applyForce` to move them, neither can we use `applyImpulse` nor `setLinearVelocity`. To move a kinematic rigid body you have to set it’s physics world transform (position and rotation ) from your 3d world. So while in the case of dynamic rigid bodies we get the current position and rotation from the physics world and update our 3d objects, in kinematic rigid bodies reverse is the case: get the current position and rotation from our 3d objects and update the physics objects.

To demonstrate this we will add a kinematic box to our scene to be moved around using the arrow keys (←↑↓→).

Back to our code. Under the variable declaration section add

`let kObject = null, kMoveDirection = { left: 0, right: 0, forward: 0, back: 0 }, tmpPos = new THREE.Vector3(), tmpQuat = new THREE.Quaternion();`

`kObject` will be our handle to the kinematic object while `kMoveDirection` just like `moveDirection` will hold the keypress direction for moving the kinematic object. `tmpPos` and `tmpQuat` are temporary vector and quaternion respectively.

Still in this section add `const FLAGS = { CF_KINEMATIC_OBJECT: 2 }`

Just like the case for the constant `STATE`, `FLAGS` is an enum type in the bullet source but was not included in ammo.idl though its value still gives the expected result.

When a rigid body is flagged as kinematic using `FLAGS.CF_KINEMATIC_OBJECT` ammojs will treat is as such.

Next up is to create our kinematic box

Add the above to the code after `createBall()` method definition. There is no much different between this and others we’ve been using to create physics objects except for the line highlighted below that flags it as a kinematic object:

`body.setActivationState( STATE.DISABLE_DEACTIVATION );body.setCollisionFlags( FLAGS.CF_KINEMATIC_OBJECT );`

Now call `createKinematicBox()` from `start()` method preferably after `createBall()` .

Your `start()` method should currently look like

`function start (){   tmpTrans = new Ammo.btTransform();   setupPhysicsWorld();   setupGraphics();   createBlock();   createBall();   createKinematicBox();   setupEventHandlers();   renderFrame();}`

If you check your browser at this stage you should see our box right there in the scene. Try moving the ball against it and notice that it is not affected by the collision.

Now to the important part. Moving the box.

Let’s handle the `keydown` and `keyup` of the keyboard’s arrow keys. Add the below code to the `switch…case` statement in `handleKeyDown()`

`case 38: //↑: FORWARD   kMoveDirection.forward = 1   break;   case 40: //↓: BACK   kMoveDirection.back = 1   break;   case 37: //←: LEFT   kMoveDirection.left = 1   break;   case 39: //→: RIGHT   kMoveDirection.right = 1   break;`

Equally add the following to that of `handleKeyUp()`

`case 38: //↑: FORWARD   kMoveDirection.forward = 0   break;   case 40: //↓: BACK   kMoveDirection.back = 0   break;   case 37: //←: LEFT   kMoveDirection.left = 0   break;   case 39: //→: RIGHT   kMoveDirection.right = 0   break;`

Before adding the method to move our kinematic box, let’s put in place some helpful variables.

To the variable declaration section add

`let ammoTmpPos = null, ammoTmpQuat = null;`

Proceed to `start()` method, after the line that has

`tmpTrans = new Ammo.btTransform();`

`ammoTmpPos = new Ammo.btVector3();ammoTmpQuat = new Ammo.btQuaternion();`

Good.

It’s time to finally move our kinematic box.

Paste the following method definition after that of `moveBall`

Let’s explain what’s happening above:

• First, directions in `kMoveDirection` are resolved and used in translating the box in 3d world.
• Next, the 3d box’s world transform (position and quaternion) is obtained.
• Lastly we get the physics rigid body attached to the 3d box, retrieve it’s motion state and set its world transform with that obtained from the 3d box.

That it is.

Oh, one more, add a call to `moveKinematic()` in `renderFrame()` just after `moveBall()`. `renderFrame()` should now look more like

`function renderFrame(){   let deltaTime = clock.getDelta();     moveBall();   moveKinematic();   updatePhysics( deltaTime );   renderer.render( scene, camera );   requestAnimationFrame( renderFrame );}`

Having done everything that has been outlined in this tutorial, you should have your final code looking like this . Press the arrow keys to move the box around. Notice how the box can push the ball around but is itself not affected.

Here is an online demo of it.

As a bonus I’ve added this link containing the above demo but modified to shoot out balls on mouse click (source code)

Phew!!. That’s it once again.

Feel free to modify the codes, explore and experiment as much as you like. If there is any mistake do let me know, I will be delighted to make corrections.

Enjoys.

--

--

A Software Engineer, PolyMath, with strong passion for CGI/3D