Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Box collides differently on left and right sides #12

Closed
jmfd opened this issue Apr 17, 2014 · 3 comments
Closed

Box collides differently on left and right sides #12

jmfd opened this issue Apr 17, 2014 · 3 comments
Labels

Comments

@jmfd
Copy link
Contributor

jmfd commented Apr 17, 2014

Dynamic Box (A) falling on static Box (B) will collide very differently if it is on the right or left side. If on the right side, it will bounce off as I'd expect. On Box A's left side, it will stay on top of Box (B).

wrongphysics

My glancing seems to show that the Resolver.solveVelocity is giving a different bodyB.anglePrev on the second contact, but I'm no expert on why!

See this simple repro case:

<html>
    <head>
        <script type="text/javascript" src="Matter.js"></script>
    </head>
    <body>
            <div id="canvas-container"></div>
    </body>
</html>

<script>

var container = document.getElementById('canvas-container');
var engine = Matter.Engine.create(container);

engine.world.gravity.y = 1;
engine.render.options.showDebug = true;
engine.render.options.showAngleIndicator = true;

Matter.World.add(engine.world, Matter.Bodies.rectangle(285.5, 323.5, 102, 102, { isStatic: true, density: 1.0, friction: 0.0, restitution: 1.0 }));
Matter.World.add(engine.world, Matter.Bodies.rectangle(380.5, 25.5, 102, 102, { isStatic: false, density: 1.0, friction: 0.0, restitution: 1.0 }));
Matter.World.add(engine.world, Matter.Bodies.rectangle(193.5, 25.5, 102, 102, { isStatic: false, density: 1.0, friction: 0.0, restitution: 1.0 }));

Matter.Engine.run(engine);

</script>
@liabru liabru added the bug label Apr 17, 2014
@liabru
Copy link
Owner

liabru commented Apr 17, 2014

Can you try adding the following after you set the render options:

engine.broadphase.current = 'bruteForce';

This will swap the bruteforce broadphase in rather than the default grid broadphase.

I tested this and it seems to prevent the problem, so it indicates an issue with the grid broadphase.
I'll investigate and try get it fixed, thanks for reporting this!

@jmfd
Copy link
Contributor Author

jmfd commented Apr 22, 2014

I does not look like changing to the bruteForce broadphase works around the problem; I can still reproduce with this method.

By simply adding the line it looks like it fixes the problem, but I think it is changing some of the collision ordering in SAT.collides() which has the result of masking the bug (from what I can tell, of course, a little on this below).

Using the above code, change the rectangle adding order to this:

Matter.World.add(engine.world, Matter.Bodies.rectangle(380.5, 25.5, 102, 102, { isStatic: false, density: 1.0, friction: 0.0, restitution: 1.0 }));
Matter.World.add(engine.world, Matter.Bodies.rectangle(285.5, 323.5, 102, 102, { isStatic: true, density: 1.0, friction: 0.0, restitution: 1.0 }));
Matter.World.add(engine.world, Matter.Bodies.rectangle(193.5, 25.5, 102, 102, { isStatic: false, density: 1.0, friction: 0.0, restitution: 1.0 }));

You'll see this still reproduces the problem when using the bruteForce broadphase.

Side information -- I originally discovered this because on a simpler example it looked like the restitution was wrong with the bruteForce method. Try these two add lines:

Matter.World.add(engine.world, Matter.Bodies.rectangle(321.5, 337.5, 383, 17, { isStatic: true, density: .5, friction: 1, restitution: 0, angle: 0}));
Matter.World.add(engine.world, Matter.Bodies.rectangle(300, 67, 102, 102, { isStatic: false, density: 0.5, friction: 1, restitution: 0.8, angle: 0}));

It doesn't bounce at all. In fact, if you move the box over to the left, it doesn't do a flat bounce:

Matter.World.add(engine.world, Matter.Bodies.rectangle(321.5, 337.5, 383, 17, { isStatic: true, density: .5, friction: 1, restitution: 0, angle: 0}));
Matter.World.add(engine.world, Matter.Bodies.rectangle(200, 67, 102, 102, { isStatic: false, density: 0.5, friction: 1, restitution: 0.8, angle: 0}));

However, changing the ordering makes it bounce as expected:

Matter.World.add(engine.world, Matter.Bodies.rectangle(300, 67, 102, 102, { isStatic: false, density: 0.5, friction: 1, restitution: 0.8, angle: 0}));
Matter.World.add(engine.world, Matter.Bodies.rectangle(321.5, 337.5, 383, 17, { isStatic: true, density: .5, friction: 1, restitution: 0, angle: 0}));

It looks like the difference is that this line is being called in SAT.collides():

        if (Vector.dot(collision.normal, Vector.sub(bodyB.position, bodyA.position)) > 0) {
            collision.normal = Vector.neg(collision.normal);
        }

And this is due to bodyA and bodyB just being swapped when passed into the function. The ordering doesn't seem to matter with the grid broadphase, but let me know if you'd like me to file any individual bugs on these.

@liabru
Copy link
Owner

liabru commented Apr 22, 2014

Interesting, thanks for providing these cases, I'll take a look when I can.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants