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

it’s time for keyboard interactivity

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.

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

Our starting point
let ballObject = null, 
moveDirection = { left: 0, right: 0, forward: 0, back: 0 }
const STATE = { DISABLE_DEACTIVATION : 4 }
let ball = new THREE.Mesh(new THREE.SphereBufferGeometry(radius), new THREE.MeshPhongMaterial({color: 0xff0505}));
let ball = ballObject = new THREE.Mesh(new THREE.SphereBufferGeometry(radius), new THREE.MeshPhongMaterial({color: 0xff0505}));
body.setActivationState( STATE.DISABLE_DEACTIVATION );
function start (){  tmpTrans = new Ammo.btTransform();  setupPhysicsWorld();  setupGraphics();
createBlock();
createBall();
setupEventHandlers();
renderFrame();
}

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

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

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.

let kObject = null, 
kMoveDirection = { left: 0, right: 0, forward: 0, back: 0 },
tmpPos = new THREE.Vector3(), tmpQuat = new THREE.Quaternion();
body.setActivationState( STATE.DISABLE_DEACTIVATION );
body.setCollisionFlags( FLAGS.CF_KINEMATIC_OBJECT );
function start (){   tmpTrans = new Ammo.btTransform();   setupPhysicsWorld();   setupGraphics();
createBlock();
createBall();
createKinematicBox();
setupEventHandlers();
renderFrame();
}
a dynamic ball and a kinematic box
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;
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;
let ammoTmpPos = null, ammoTmpQuat = null;
tmpTrans = new Ammo.btTransform();
ammoTmpPos = new Ammo.btVector3();
ammoTmpQuat = new Ammo.btQuaternion();
function renderFrame(){   let deltaTime = clock.getDelta();

moveBall();
moveKinematic();
updatePhysics( deltaTime ); renderer.render( scene, camera ); requestAnimationFrame( renderFrame );}
primitive ball shooter

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store