schteppe / cannon.js

A lightweight 3D physics engine written in JavaScript.
http://schteppe.github.com/cannon.js
MIT License
4.64k stars 701 forks source link

The Chuck Noris Bug - some clues #407

Open robrohan opened 5 years ago

robrohan commented 5 years ago

I think there is an issue when doing convex v. convex - I think it's somewhere in the solver in some specific circumstances. It's not that easy to reproduce (I've seen it called Chuck Noris since it throws objects in random directions at great speeds). I couldn't find the original reported bug, so I thought I'd just leave this here.

If I create a scene with no ground (meaning, no plane rotated to X), and create two convex polygons (one to "stand on" and one as a wall), and also create a box when I push the box into the wall I can recreate the issue. All of these are CCW winding.

If the wall is at 0,0,0 the collision response works fine:

atzero ok

However, if I move the convex off of zero (by one in the positive X in this example), the collision gets solved by moving the box to the other side of the convex polygon:

offzero notok

I the same thing happens if I go from the other size - 0 collisions work fine, -1 it pops to the other side.

Stepping through the code, it looks like vlambda in the solver (around here https://github.com/schteppe/cannon.js/blob/569730f94a1d9da47967a24fad0323ef7d5b4119/src/solver/GSSolver.js#L119) sometimes goes from a value of, say, -1.3 to something like -230. Obviously, I am not sure why :-/. Fixing it is turning out to be beyond my skill to heal.

I can't provide a code example as I am using a ported version of cannon, and it's within a whole other context. While this could indeed be caused by my implementation / something I've done, I've seen this behaviour in normal cannon - hopefully these clues help.

I should also note, that with a ground plane and just a bunch of cubes are spheres, the collisions seem to always work - https://mesh.robrohan.com/#level:physics

Should also probably note that the walls and the floor are Static, and the box is Dynamic (with a mass of 75), and gravity in the scene is set to -30 in the Y.

liffiton commented 5 years ago

I'm not sure whether my case is relevant to yours, but I had similar issues with collisions between a dynamic and a static convex resulting in the dynamic body "mushing through" the static one. I'll put my solution here in case it's useful to someone with the same circumstances.

In my case (and this is where I'm not sure if it's relevant to you, directly), it was caused by the fact that my static body had previously been dynamic, and I missed a step or two in "freezing" it into a static body . Initially, I had just set body.type = CANNON.Body.STATIC to change a dynamic body to static. This made it stop moving, and things mostly collided with it correctly, but not always. I additionally had to do, on the newly-static body:

body.mass = 0;
body.updateMassProperties();
body.updateSolveMassProperties();

Collisions then worked without issue.

Setting the mass and calling updateSolveMassProperties() seemed most critical, but updateMassProperties() seemed reasonable as well.

I also called body.sleep(), but I don't know that that was necessary.