Wednesday, August 22, 2012

Grouping Physijs Objects!

‹prev | My Chain | next›

Sometimes it really helps to read the documentation. Or remember it.

For the past several days, I have struggled with Physijs' seeming lack of ability to group objects. Well, it seems that Physijs not only has this ability, but has a wiki page describing how to do it.

I could have sworn that I tried that solution. That is, I thought I had added the river banks to the river when both were Physijs Mesh objects. Maybe not.

So I add the water:
  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);
Then I add the river banks to the water (not the scene):
  var bank1 = new Physijs.BoxMesh(
    new THREE.CubeGeometry(1500, 100, 100),
    Physijs.createMaterial(
      new THREE.MeshNormalMaterial(), 0.2, 0.9
    ),
    0
  );
  bank1.position.z = -250;
  water.add(bank1);
I do the same for the other river bank, then add the parent object—the water—to the scene:
  scene.add(water);
And... it works.

My river banks now bounce my raft as desired:


Holy cow. I have wasted three days of this chain because I couldn't read the documentation. The most important part of the wiki entry (at least the one that I failed to consider) was:
The only thing you need to remember when working with compound objects is all children must be added to the parent before the parent is added to the scene. When a parent is put into the scene its shape is finalized and cannot be added to.
I do not have a git commit to verify it, but I am quite certain that, when I tried this on my own, I added the water to the scene and then added the associated river banks. And indeed, if I remove the post-banks scene.add(water) and instead do it right after creating the water:
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);
Then the raft passes right through the river banks. I am such an idiot.

The real reason that I was looking into the documentation was refreshing my memory on Physijs events. Why I remembered that the wiki contained events, but failed to even look at the documentation during three days of struggle is beyond me. Anyhow...

I am interested in applying a pushing force on the raft from the water. My first pass is going to be applying a force in the direction in which the river is pointing as soon as the raft hits the river. Tracer bulletting the solution, I start with:
  water.addEventListener('collision', function() {
    console.log("water collision!");
  });
I am uncertain why, but I see more of these events logged than expected. When the page loads, there are three events immediately logged. I also see these events when the raft hits the river banks. I cannot quite rationalize why that might be. I log the colliding object:
water.addEventListener('collision', function(object) {
    console.log("water collision!");
    console.log(object);
  });
But it is always the raft as evidenced by the torus geometry. I had thought perhaps the river bank was somehow being forced down into the water. I table this for now in favor of adding a force to the raft, which I accomplish with:
  water.addEventListener('collision', function(object) {
    raft.applyCentralForce(new THREE.Vector3(1e9 * cos, 0, 1e9 * sin));
  });
And that seems to work. At least well enough for a first pass. I call it a night here, having finally made significant progress. Up tomorrow: I am ready to add controls to my raft.


Day #486

1 comment:

  1. Thank you so much for this post! Going through similar woes.

    ReplyDelete