rapier.js icon indicating copy to clipboard operation
rapier.js copied to clipboard

JavaScript 2D: creating more than 1 rigidBody results in invalid handles and positions

Open britalmeida opened this issue 2 years ago • 2 comments

Version: "@dimforge/rapier2d": "0.11.2"

I'm just getting started with RapierJS and I'm not being able to extend the example to have multiple RigidBodies. Only the first seems to work, but I'm not sure why. I get no errors.

Rigid Bodies except the first get a handle which looks faulty. The position starts out undefined for all bodies.

  0 undefined
  5e-324 undefined
  1e-323 undefined

After one step, all positions converge to the first (x = 0.30000001192092896)

How I created the bodies: (adding colliders makes no difference).

  let rigidBodyDesc = RAPIER.RigidBodyDesc.dynamic()
    .setTranslation(0.3, 0.3);
  let rigidBody = world.createRigidBody(rigidBodyDesc);
  console.log(rigidBody.handle, rigidBody.position)

  let rigidBodyDesc2 = RAPIER.RigidBodyDesc.dynamic()
    .setTranslation(0.7, 0.3);
  let rigidBody2 = world.createRigidBody(rigidBodyDesc2);
  console.log(rigidBody2.handle, rigidBody2.position)

  let rigidBodyDesc3 = RAPIER.RigidBodyDesc.dynamic()
    .setTranslation(1.0, 0.3);
  let rigidBody3 = world.createRigidBody(rigidBodyDesc3);
  console.log(rigidBody3.handle, rigidBody3.position)

britalmeida avatar Dec 15 '23 19:12 britalmeida

The handles you are getting are correct. Handles are some complex integers manufactured on the WASM side for uniqueness. When printed out as a javascript number, they won’t make any sense. In general, you should just assume that they are opaque identifier for your rigid-body.

There is no position field in rigid-bodies. You need to call .translation().

You might be interested in looking at some scene initialization examples as well as the user-guide.

sebcrozet avatar Dec 15 '23 20:12 sebcrozet

My bad! Indeed I was using .position instead of .translation(), which explains the undefined.

But that wasn't all. I made that mistake only when typing the example code above for this issue report. I had a different mistake in my actual code, and that was that I somehow I ended up with this:

  world.step();
  world.forEachRigidBody((handle: RigidBodyHandle) => {  // bad
    const body = world.getRigidBody(handle);             // bad
    let position = body.translation();
    ...
  }

The problem being that I was iterating bodies and thinking I was getting handles. It should have been:

  world.step();
  world.forEachRigidBody((body: RigidBody) => {          // good
    let position = body.translation();
    ...
  }

So it's all my mistake, no bug to see here :) But it got quite confusing that I had no errors in the log and all objects look converged to the same position. That's because const body = world.getRigidBody(handle); with a handle which isn't a handle does return a valid looking body (the first one, with handle 0). So my iteration on "all bodies" was just hitting the first one multiple times. When I tried to inspect more, I typed slightly different code and saw that the other handles look like float denormals and thought the problem was on the Rapier side. Would it be very hard to type check the function calls I used?

The examples code is really useful! I had found the examples running as a demo, but not the respective code. I'd suggest linking to the code in the demo page. ☺️

britalmeida avatar Dec 27 '23 11:12 britalmeida