dimforge / rapier.js

Official JavaScript bindings for the Rapier physics engine.
https://rapier.rs
Apache License 2.0
390 stars 55 forks source link

Unstable core features #283

Open Noobulater opened 1 week ago

Noobulater commented 1 week ago

Hi all, love the work you are all doing here, but recently ran into an issue with some core features, such as setting position and velocity data, leading to a WASM unreachable error.

image

This instability was almost enough to make me swap physics libaries, so I hope it gets addressed.

Here's the situation: This is on a Velocity based Kinematic body. I need to run 1-15 "TICKS" as fast as possible, each completing a round trip of user input -> update bodies with new forces -> run physics simulation -> report body's physics state back to the simulation. However, doing so at a high frequency will lead to a crash (not guarenteed, and more frequent the higher the tick rate)

Noobulater commented 1 week ago
if (p != null)
    body.setTranslation(new Vector3(p[0], p[1], p[2]))

  if (q != null)
    body.setRotation(new Quaternion(q[0] || 0, q[1] || 0, q[2] || 0, q[3] || 1))

  if (v != null)
    body.setLinvel(new Vector3(v[0], v[1], v[2]))

  if (aV != null)
    body.setAngvel(new Vector3(aV[0], aV[1], aV[2]))
for (const cID in components) {
      const { Controller, body, rigidBodyCollider, grounded } = components[cID]
      if (Controller && rigidBodyCollider) {
        const vel = body.linvel()

        if (vel.x > 0 || vel.x < 0)
          vel.x /= body.mass()

        if (vel.y > 0 || vel.y < 0)
          vel.y /= body.mass()

        if (vel.z > 0 || vel.z < 0)
          vel.z /= body.mass()

        if (grounded)
          vel.y = 0
        else
          vel.y -= 0.25

        Controller.computeColliderMovement(
          rigidBodyCollider,           // The collider we would like to move.
          vel, // The movement we would like to apply if there wasn’t any obstacle.
        )
        const movement = Controller.computedMovement()
        if (movement.x > 0 || movement.x < 0)
          movement.x /= physics.timestep
        if (movement.y > 0 || movement.y < 0)
          movement.y /= physics.timestep
        if (movement.z > 0 || movement.z < 0)
          movement.z /= physics.timestep

        body.setLinvel(movement)

        components[cID].grounded = Controller.computedGrounded()
      }
    }

Relevant code in case it helps. All values are of the right type.

Noobulater commented 1 week ago

Tried downgrading to 0.11.1, but still got the issue.

Edit: After a lot of attempts to diagonse this, I still get the issue, but I can't recreate a state where it fails consistently. The snapshot I load when the error occurs work if loaded manually, which makes me think there is some sort of race condition internally with the library.

This issue is a deal breaker for me and sadly I can't use this library until it's addressed.

Noobulater commented 1 week ago

Got this reply on the discord, but not sure it works since I've switched off the library

Hello. 
I encountered this problem once. It was caused by some references of Rapier body objects that were kept in an array after the bodies were removed from the physics world. I think it messed up the lifecycle somehow.
I fixed it by only keeping their "handle" and not a reference to the full object.
I hope it can help.