‹prev | 
My Chain | 
next›
Yesterday, I discovered the benefits of 
__dirtyRotation in 
Physijs, this physics engine for 
Three.js. I used it yesterday to prevent my player from spinning out of control after contact with other objects. Tonight, I plan to use it to restore the spin-to-walk ability.
I am not going to rewrite the Three.js first person controls, but I need some of that ability. I start with global variables that hold state (moving and state):
var moving = false;
var controlState = {};Next, I need a keydown handler to set the state:
document.addEventListener("keydown", function(event) {
  // Last wins (for now) because we set the velocity, not apply force
  function setState(state) {
    moving = true;
    controlState = {};
    controlState[state] = true;
  }
  
  var speed = 500;
  var code = event.which || event.keyCode;
  if (code == 0x57) { // w
    setState("moveForward");
    a_frame.setLinearVelocity({z: -speed, y: 0, x: 0 });
  }
  // ...
});I feel a little bad about overwriting 
controlState and the velocity like that, but it works for now—movement is only in one direction.
I also use a corresponding keyup handler to reset 
controlState and mark the avatar as no longer moving:
document.addEventListener("keyup", function(event) {
  function stopState(state) {
    if (controlState[state]) {
      moving = false;
      controlState = {};
    }
  }
  var code = event.which || event.keyCode;
  if (code == 0x57) { // w
    stopState("moveForward");
    // a_frame.setLinearVelocity({z: 0, y: 0, x: 0 });
  }
  // ...
});This allows me to restore the motion of the legs when 
moving is 
true. I can also spin the avatar in the proper direction depending on the controls' state:
var w = 500;
function render() {
  var t_float = clock.getElapsedTime()
    , t = t_float * 1000
    , amplitude = (w/2 - Math.abs((t % (2*w)) - w))/w;
  if (moving) {
    avatar_left_leg.rotation.x = amplitude*(Math.PI/6);
    // ...
    if (controlState.moveLeft) spinAvatar(-Math.PI/2);
    // ...
  }
  else {
    spinAvatar(0);
  }
  scene.simulate(); // run physics
  renderer.render(scene, camera);
}Even the 
spinAvatar() function still works.  It works because it spins the avatar inside the Physijs frame so no changes are required:
function spinAvatar(angle) {
  new TWEEN.Tween( { y: avatar.rotation.y } )
      .to( { y: angle }, 100 )
      .onUpdate( function () {
         avatar.rotation.y = this.y;
      })
      .start();
}So it turns out that I did not need any additional use of 
__dirtyRotation. As long as it keeps the frame of reference steady, everything just works. Nice.
This is all going so smoothly. Something is going to go horribly wrong soon. I just know it.
But failure does not arrive when I set up invisible fences around the island:
  scene = new Physijs.Scene;
  var fence = new Physijs.BoxMesh(
    new THREE.CubeGeometry(ISLAND_WIDTH, 1000, 10),
    new THREE.Material(),
    0
  );
  fence.position.z = -ISLAND_HALF;
  fence.position.y = 500;
  scene.add(fence);
The last argument of zero to the 
BoxMesh constructor specifies a mass of zero, which is interpreted as a static object in Physijs. In other words, my fence will not yield, keeping the avatar on the island:
I finally do run into a small problem with the avatar's interaction with the ball that I have left on the island for the avatar's amusement. My avatar can no longer budge it:
What fun is that?
Fortunately, it does not take too long to identify the problem. I specified a mass of 1000 for my avatar's frame of reference / Physijs box:
  a_frame = new Physijs.BoxMesh(
    new THREE.CubeGeometry(250, 250, 250),
    new THREE.Material(),
    1000
  );
It seems that, in Physijs, 1000 is very light. I suppose it is measured in grams.
Anyhow, with a slightly heavier mass:
  a_frame = new Physijs.BoxMesh(
    new THREE.CubeGeometry(250, 250, 250),
    new THREE.Material(),
    1000*1000*1000
  );
I can now send my ball rolling and bouncing around:
It is literally minutes of fun!
Actually, what this really means is that I seem to have gotten the hang of Physijs. 
Day #481