Polygon collision

Official forum for the Chipmunk2D Physics Library.
Post Reply
derula
Posts: 4
Joined: Mon Feb 03, 2014 2:42 pm
Contact:

Polygon collision

Post by derula »

Hi!

First of all, cool free physics engine, I like it so far and find it quite easy to handle with the Ruby integrations and Gosu.

I feel like this is a dumb question and has probably been asked by millions of noobs already, but I couldn't find anything about it anywhere.

So I made a static poly ramp and a circle to roll up and down the ramp, and it worked great. But if I make the circle a cube, it stops working. Apparently, the cube wants to collide with the ramp's inside edges rather than its outside edges.

I've tried a couple things, like turning off friction and not giving the cube infinite moment of inertia, but nothing worked. I've tried changing the winding but then it just crashes.

Any ideas?
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Polygon collision

Post by slembcke »

That's... very weird.

Do you know what version of Chipmunk it is? Off the top of my head, try reversing the polygon vertex order. You are supposed to do them with a certain winding direction, and depending on how Chipmunk is compiled there may or may not be an assertion if you do it wrong. I forget exactly what happens in older versions when the winding direction is wrong, but inside out polygons sounds like a reasonable way for it to break.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
derula
Posts: 4
Joined: Mon Feb 03, 2014 2:42 pm
Contact:

Re: Polygon collision

Post by derula »

Thanks for the quick reply!
slembcke wrote:That's... very weird.

Do you know what version of Chipmunk it is? Off the top of my head, try reversing the polygon vertex order. You are supposed to do them with a certain winding direction, and depending on how Chipmunk is compiled there may or may not be an assertion if you do it wrong. I forget exactly what happens in older versions when the winding direction is wrong, but inside out polygons sounds like a reasonable way for it to break.
The version is 5.3.4, I think (well there's 'const char *cpVersionString = "5.3.4";' in the chipmunk.c, anyway), but I know that it gives me an error if I try the vertices in backwards order. And both (actually, all three) polys are counter-clockwise anyway.

Well, maybe it helps if I post the actual polys, so here:
Static:
[[-320, 240], [0, 240], [0, 200], [-320, 160]]
[[0, 240], [320, 240], [320, 160], [0, 200]]
Moving:
[[25,-25], [-25,-25], [-25,25], [25,25]]

Thought it must be something obvious I'm doing wrong... I do think I'm dropping the moving one from above... and it worked with a circle :/
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Polygon collision

Post by slembcke »

O_o I have no idea then. A video might help I guess?

I feel like the only time I've ever seen inside out polygons happen is when I was developing the collision detection code and debugging it. One thing that can cause extremely weird collisions is if the moment of inertia of the body is off by a lot. If you set it to infinity it will not allow the object to rotate, but might shed some light on what is going on with the collisions.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
derula
Posts: 4
Joined: Mon Feb 03, 2014 2:42 pm
Contact:

Re: Polygon collision

Post by derula »

Huh. Well I did have a moment of infinity, so I changed it back to normal just to make sure and yeah it's pretty much the same, except then it turns. I turned off my collision handler, no change. There is no collision detected until the bottom of the square touches the bottom of the ramp, and then it's trapped in there. Hitting my jump button which applies an (upwards) impulse makes it teleport down by like 10 pixels. I can control it with the arrow keys (by manually changing the speed), and in the center of the screen where the two ramps meet, it moves slower (probably only moves there because I'm forcing speed on it without checking for collisions) as it inches through the wall between the ramps.
I tried to record a video, but it failed, I guess partly due to my low-end laptop.

I tried to make a simple testcase, but then nothing worked and after the second step, my body's y coordinate became NaN and stayed there.

...
dooxe
Posts: 2
Joined: Wed May 13, 2015 1:28 am
Contact:

Re: Polygon collision

Post by dooxe »

Hi there,

I know that this post is a little old, but I work on a javascript version of Chipmunk, and I have the same problem.
The fact is that the dynamic body of the hero seems to sink inside other bodies (that are static), check the demo :
http://dooxe-creative.net/gwe/
(you can go left, right, with arrows and jump with the spacebar).

Here is some come if it can help (http://dooxe-creative.net/gwe/src/states/MapState.js) :

Code: Select all

/**
 * Created by dooxe on 12/05/2015.
 */
///
///
/// @author dooxe
///
define(function(require)
{
    var utils = require('utils/utils');

    return utils.extend(new Kiwi.State('MapState'),
    {
        //
        preload         : function()
        {
            console.log('SampleState : preload');
            Kiwi.State.prototype.preload.call(this);
            this.addJSON('tilemapjson', 'data/maps/Map_002.tiled.json');
        },

        //
        create      : function()
        {
            console.log('SampleState : create');
            Kiwi.State.prototype.create.call(this);

            //Initialise the physics debugger
            this.game.chipmunkDebug.init();


            var self = this;

            // Physical world
            var space = this.space = this.game.chipmunk.space;
            space.gravity = cp.v(0, 1000);
            space.iterations = 80;
            space.sleepTimeThreshold = 0.5;
            space.collisionSlop = 0.5;

            //
            var createStaticBody = function()
            {
                var body = new cp.Body(Infinity,Infinity);
                body.nodeIdleTime = Infinity;
                return body;
            };

            //	Collision Map
            var map			= JSON.parse(this.data.tilemapjson.data);
            var collisions	= map.collisions;
            for(var y = 0; y < map.height; ++y)
            {
                for(var x = 0; x < map.width; ++x)
                {
                    var c		= collisions[x][y];
                    if(c > 0)
                    {
                        var width = 32;
                        var height = 32;
                        var mass = width * height * 1 / 10000;
                        var tw      = map.tilewidth;
                        var th      = map.tileheight;
                        var position    = cp.v(map.tilewidth/2 + x * map.tilewidth, map.tileheight/2 + y * map.tileheight);
                        switch(c)
                        {
                            //  Square
                            case    1 :
                            {
                                var rock = createStaticBody();
                                rock.setPos(position);
                                var shape = space.addShape(new cp.BoxShape(rock, width, height));
                                shape.setFriction(50);
                                break;
                            }
                            //  Bottom-Left triangle
                            case    2 :
                            {
                                var verts   = [
                                    0, 0, tw, th, 0, th, 0, 0
                                ];
                                cp.convexHull(verts, null, 2);
                                var col     = createStaticBody();
                                var pos     = cp.v(x * map.tilewidth, y * map.tileheight);
                                col.setPos(pos);
                                var shape   = space.addShape(new cp.PolyShape(col,verts,cp.v(0, 0)));
                                shape.setFriction(50);
                                break;
                            }
                            //  Top-Left triangle
                            case    3 :
                            {
                                var verts   = [
                                    0, 0, tw, 0, 0, th, 0, 0
                                ];
                                cp.convexHull(verts, null, 2);
                                var col     = createStaticBody();
                                var pos     = cp.v(x * map.tilewidth, y * map.tileheight);
                                col.setPos(pos);
                                var shape   = space.addShape(new cp.PolyShape(col,verts,cp.v(0, 0)));
                                shape.setFriction(50);
                                break;
                            }
                            //  Top-Right triangle
                            case    4 :
                            {
                                var verts   = [
                                    0, 0, tw, 0, tw, th, 0, 0
                                ];
                                cp.convexHull(verts, null, 2);
                                var col     = createStaticBody();
                                var pos     = cp.v(x * map.tilewidth, y * map.tileheight);
                                col.setPos(pos);
                                var shape   = space.addShape(new cp.PolyShape(col,verts,cp.v(0, 0)));
                                shape.setFriction(50);
                                break;
                            }
                            //  Bottom-Right triangle
                            case    5 :
                            {
                                var verts   = [
                                    tw, 0, tw, th, 0, th, tw, 0
                                ];
                                cp.convexHull(verts, null, 2);
                                var col     = createStaticBody();
                                var pos     = cp.v(x * map.tilewidth, y * map.tileheight);
                                col.setPos(pos);
                                var shape   = space.addShape(new cp.PolyShape(col,verts,cp.v(0, 0)));
                                shape.setFriction(50);
                                break;
                            }
                        }
                    }
                }
            }

            //  Create the hero
            var heroW   = 25;
            var heroH   = 25;
            var mass    = 500;
            var body = space.addBody(new cp.Body(mass, cp.momentForBox(mass, heroW, heroH)));
            body.setPos(cp.v(9*32,7*32));
            var box = space.addShape(new cp.BoxShape(body, heroW, heroH));
            box.setFriction(500000);
            this.hero = box;

            //  Keyboard management
            this.keyboard = this.game.input.keyboard;
            this.game.input.keyboard.onKeyDownOnce.add( this.keyDownOnce, this );
            this.game.input.keyboard.onKeyUp.add( this.keyUp, this );

            this.leftK  =  this.keyboard.addKey(Kiwi.Input.Keycodes.LEFT,       true);
            this.rightK =  this.keyboard.addKey(Kiwi.Input.Keycodes.RIGHT,      true);
            this.jumpK  =  this.keyboard.addKey(Kiwi.Input.Keycodes.SPACEBAR,   true);
            this.jumpV  = cp.v(0,0);
        },

        keyDownOnce : function(keyCode, key)
        {
            this.hero.body.applyForce(cp.v(0,50),this.hero.body.p);
            if(keyCode == Kiwi.Input.Keycodes.SPACEBAR)
            {
                this.jumpV  = cp.v(0,-50);
            }
        },

        keyUp       : function(keyCode, key)
        {
            if(keyCode == Kiwi.Input.Keycodes.SPACEBAR)
            {
                this.jumpV  = cp.v(0,0);
            }
        },

        buttonDownOnce 	: function(button)
        {
            console.log(button);
        },

        //
        update 		: function()
        {
            Kiwi.State.prototype.update.call(this);

            var heroPos = this.hero.body.p;
            var moved = false;

            var newVelo = cp.v(0,0);
            if(this.rightK.isDown)
            {
                newVelo.x = 50;
                moved = true;
            }
            if(this.leftK.isDown)
            {
                newVelo.x = -50;
                moved = true;
            }
            if(moved)
            {
                //this.hero.body.applyForce(newVelo, this.hero.body.local2World(this.hero.body.p));
                this.hero.body.setVel(this.hero.body.getVel().add(newVelo));
            }
            this.hero.body.setVel(this.hero.body.getVel().add(this.jumpV));

            //  Lock the hero's body rotation
            this.hero.body.setAngVel(0);
            this.hero.body.setAngle(0);

            //  Centering the camera on the hero
            this.game.cameras.defaultCamera.transform.x = -this.hero.body.p.x + this.game.stage.width/2;
            this.game.cameras.defaultCamera.transform.y = -this.hero.body.p.y + this.game.stage.height/2;
        }
    });
});
I have already searched for some help, but I didn't find a solution to this problem.

Do you have an idea of what happens ?

Thanks
derula
Posts: 4
Joined: Mon Feb 03, 2014 2:42 pm
Contact:

Re: Polygon collision

Post by derula »

This isn't the problem I was having... here's a mockup of what it would look like for me: http://imgur.com/kdF5oi2

Basically, the "ground" did act as a kind of "ground", however instead of standing on it, objects ended up hanging from it. So I guess it was more the "ceiling" type of ground.

(But only for other polygon bodies, IIRC.)
dooxe
Posts: 2
Joined: Wed May 13, 2015 1:28 am
Contact:

Re: Polygon collision

Post by dooxe »

Oh ok I see ! Sorry about that.
Post Reply

Who is online

Users browsing this forum: No registered users and 24 guests