The ghost effect
- How to prevent all meshes from passing through the ground?
Respawn
- What’s the best way to slow down a mesh that has been positioned (from negative y: -10 to positive y: 10), so that it doesn’t go through the ground?
Hello! You could add a bit of thickness to the ground, and use sub time steps to make the calculations more precise: Advanced Physics Features | Babylon.js Documentation
Thanks @carolhmj. Now, with setSubTimeStep
:
const physicsEngine = scene.getPhysicsEngine();
physicsEngine.setSubTimeStep(8);
prevents meshes from passing through the floor. Still, if the speed is high, the mesh can pass through:
https://playground.babylonjs.com/#THMMS9#2
Sometimes I use box, instead of ground, to avoid this “ghost” problem, but I was hoping ground would do the trick:
Still has flaws. The more speed, the harder it is to stop
Yep, the higher the speed, the smaller the sub time step you’ll. What the physics engine does is that, at each sub time step, it will update the box’s position with the acting forces, then check the box’s position to see if it has collided. So imagine a box falling at a very high speed:
At step 1, it has not collided with the ground, so the gravity will keep acting. At step 2, the box position will be updated, and since the speed is high, it will move a lot. And since it moved so much, the engine won’t be able to detect the collision with the ground. What the sub time step does is, instead of just having step 1 and step 2, it will have step 1.1, 1.2, 1.3, etc…, so the box won’t have moved as much at every physics check, and detecting a collision is more likely. This is the same principle behind a lot of video game glitches, where moving at speeds not intended by the developers allows the player to “clip” through walls and other surfaces.
Pretty good explanation. Thanks! I understand that the problem is with the check momentum. So we have to control the speed of these meshes to avoid glitches.
Solved Respawn problem The ghost effect, Respawn
We can get the linearVelocity.y
and reverse it to be used as impulseMagnitude
. That way the mesh doesn’t keep accelerating infinitely.
const impulse = (mesh) => {
const linearVelocity = mesh.physicsImpostor.getLinearVelocity()
const impulseDirection = new BABYLON.Vector3(0, 1, 0);
const impulseMagnitude = linearVelocity.y - (linearVelocity.y * 2);
const contactLocalRefPoint = BABYLON.Vector3.Zero();
mesh.physicsImpostor.applyImpulse(
impulseDirection.scale(impulseMagnitude),
mesh.getAbsolutePosition().add(contactLocalRefPoint)
);
};
Documentation: Forces | Babylon.js Documentation