Tuesday, August 21, 2012

Poor Man's Grouping of Physijs Objects

‹prev | My Chain | next›

I remain thwarted in my efforts to group related Physijs objects inside a Three.js game, so tonight, I do it the hard way. Instead of positioning and rotating a grouped segment of objects, I will ask a generator function to create the object and add them directly to the Physijs scene.

So I switch from a more ideal generator that just generates a river segment:
river_segment = riverSegment();
  river_segment.position.x = 100;
  scene.add(river_segment);
Instead, I tell that same riverSegment() function to draw the river and its two riverbanks in addition to creating them. This is a relatively quick fix. Instead of adding my Physijs objects to a grouping THREE.Object3D object, I add them directly to the scene:
function riverSegment(scene) {
  var water = new Physijs.PlaneMesh(
    new THREE.PlaneGeometry(1500, 500),
    new THREE.MeshBasicMaterial({color: 0x483D8B})
  );
  water.position.x = 750;
  scene.add(water);

  var bank1 = new Physijs.BoxMesh(
    new THREE.CubeGeometry(1500, 100, 100),
    Physijs.createMaterial(
      new THREE.MeshNormalMaterial(), 0.2, 0.9
    ),
    0
  );
  bank1.position.x = 750;
  bank1.position.z = -250;
  bank1.__dirtyPosition = true;
  scene.add(bank1);
  // ...

  return water;
}
The problem that I had hoped to solve by grouping things involved twists and turns in the river. Rotating a single thing (the group of river segment plus banks) is much easier than rotating a bunch of things separately.

For example, I might want the river to start off rotated one direction, then to straighten out, then to turn back the other direction:
  offset = riverSegment(scene, Math.PI/8);
  offset = riverSegment(scene, 0, offset);
  offset = riverSegment(scene, -Math.PI/8, offset);
I can get this to work, but even with simple rotation, things get complicated rather quickly:
function riverSegment(scene, rotation, offset) {
  if (!offset) offset = {x: 0, z: 0};

  var length = 1500
    , z_frame = 0.5 * length * Math.sin(rotation)
    , z_offset = z_frame + offset.z
    , x_frame = 0.5 * length * Math.cos(rotation)
    , x_offset = x_frame + offset.x;

  var water = new Physijs.PlaneMesh(
    new THREE.PlaneGeometry(1500, 500),
    new THREE.MeshBasicMaterial({color: 0x483D8B})
  );
  water.position.x = x_offset;
  water.position.z = -z_offset;
  water.rotation.y = rotation;
  scene.add(water);

  var bank1 = new Physijs.BoxMesh(
    new THREE.CubeGeometry(1500, 100, 100),
    Physijs.createMaterial(
      new THREE.MeshNormalMaterial(), 0.2, 0.9
    ),
    0
  );
  bank1.position.x = x_offset;
  bank1.position.z = -z_offset -250;
  bank1.rotation.y = rotation;
  scene.add(bank1);
  // ....
  return {x: 2 * x_frame + offset.x - 50, z: 2 * z_frame + offset.z};
}

I think I may give Box2D a try with this. This solution is getting way too complicated for a simple game for kids to write.


Day #485

No comments:

Post a Comment