Cannon Physics: physics body never switches to sleep state

I noticed an issue when using the Cannon Physics Plugin, where the physics body never goes to a sleep state. To demonstrate this, please check the following playground:

In cannon the body apparently falls to sleep when the angular and directional velocity stay under a threshold for a some time. To debug I printed both the internal velocity and the one on the babylon physics impostor and additionally the cannon sleep state. The sleep state never changes from 0 to 1 or 2 (which would be sleepy or sleeping). Both velocities are the same but thereā€™s something weird going on. Even though the sphere is not moving, the velocity never really drops below 0.02 (to be precise it might drop to 0.004 but would actually increase to something around 0.02 on the next frame):

image

It makes perfect sense, the physics body never falls asleep, since the per default settings the treshold needs to be below 0.01 for at least 1 second. Please note Iā€™m deliberately ignoring the angular velocity in all cases.

I created a simliar example with cannon-es, which is not the version babylonjs is using, but should not make any differences. To reproduce I did the following:

const animate = () => {
  requestAnimationFrame(animate)
  console.log(sphereBody.velocity.lengthSquared())
}
animate()

The console log is something like this towards the end:

As you can see the velocity gets smaller on each step and eventually the sphere falls asleep.

There seems to be something wrong the the Physics Plugin for Cannon (or maybe other engines aswell? I didnā€™t check). Also this might be related to this issue: Updating the mass applies a force to the physics body - #7 by Cedric

It might be something along these lines, which cause this behaviour: Babylon.js/cannonJSPlugin.ts at master Ā· BabylonJS/Babylon.js Ā· GitHub But Iā€™m afraid I understand to little about the integration of the physics engines to be able to tell whatā€™s happening there and why

@sebavan Pinging you, since git blame says you wrote those lines, I hope thatā€˜s ok.

cc @cedric our physics champion as well

Is there any difference between our cannon and cannon-es versions @sebavan ?

There should not be (like babylon and @babylon/core) so I wonder if the sleep detection might be in cause.

I think they merged some open PRs and updated some other smaller stuff. Details can be read on the github-page: GitHub - pmndrs/cannon-es: šŸ’£ A lightweight 3D physics engine written in JavaScript.

1 Like

A quick update: I recreated my experiment from the original post with cannon.js and it shows the same behaviour like cannon-es:

So Iā€™d still assume thereā€™s something wrong on the babylonjs side :man_shrugging:

there has been reports of sleep issue with ammo too, perhaps related? Although, if i remember correctly, raggar said that an older version of ammo fixed the problem, which, at least for that case, seems like it may not be the bjs plugin.

side note, cannon-es did have some arbitrary breaking changes, like changing the shape schema to typescript enums from the original js object look up. they also removed a method that had an alias, because it had a comment over it that was like ā€œtodo , removeā€. I know this because I rewrote the original cannon to esm/typescript. I have a copy somewhere anyone wants it

1 Like

I get different ā€˜stabilizedā€™ velocity depending on gravity and physics time step.
The small velocity difference is due to the sphere penetrating a little in the ground, and the ground responding.
This said, even when setting linear velocity to 0, I donā€™t get the impostor to go to sleep.

@Cedric Any idea why that is?

No, getting deeper in this behavior will take some time. Iā€™ll do my best to check it in the coming days.

1 Like

Also switching tabs seems to throw the physics simulation off.

This can happen if delta time has spike.

Check useDeltaForWorldStep for changing it to fixed frame rate.

@Cedric Sorry to bother you again, do you have anything to go forward with this or should I search for an alternative solution?

I think I found the solution, you need to enable allowSleep on the cannon world :roll_eyes:

const plugin = scene.getPhysicsEngine().getPhysicsPlugin()
plugin.world.allowSleep = true

Updated playground: https://playground.babylonjs.com/#BEFOO#1705

I didnā€™t anticipate it was that easy of a solution :sweat_smile:

5 Likes