fredsa / playn

Cross platform game library for N≥4 platforms
0 stars 1 forks source link

Fails to process collisions between falling dynamic body and downward-moving kinematic body. #219

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Set gravity as (0, -50)
2. Create a kinematic block about 5 x 1 in size moving downward at a speed of 
.5 / second. 
3. Create a roughly 1 x 2 dynamic block about of mass 2 positioned 3 units 
above the kinematic block. 
4. Make it so the blocks should collide with one another. 

What is the expected output? What do you see instead?

The two blocks should collide and there should be a Contact object representing 
this collision. However, although the dynamic block is prevented from falling 
through the kinematic object, there is no collision object created connecting 
them and hence the behavior of the dynamic object cannot be altered based on 
the fact that it is touching another object. 

What version of the product are you using? On what operating system?

  I am using version 1.4 on Windows 7. 

Please provide any additional information below.

Here is some code to reproduce the bug. If "downwardMotion" is set to 1, a 
collision is detected, whereas if it is set to 1.5, no collision is detected. 
This is not very fast! 

public class DownwardCollisionTest implements Game{
    Body body;
    World world;
    float downwardMotion = -1.5f;

    @Override
    public void init() {
        world = new World(new Vec2(0.0f, -50.0f), true);

        createPlayer(world, 17.58f, 7.459f, 0.6513f, 0.6513f);

        // Polygon created: {{21.0, 4.0}{21.0, 5.0}{16.0, 5.0}{16.0, 4.0}}
        // With velocity: 0.0 -1.0
        Vec2[][] p = new Vec2[1][];
        p[0] = new Vec2[4];
        p[0][0] = new Vec2(21.0f, 4.0f);
        p[0][1] = new Vec2(21.0f, 5.0f);
        p[0][2] = new Vec2(16.0f, 5.0f);
        p[0][3] = new Vec2(16.0f, 4.0f);
        createBlock(world, createPolygonShape(p), 0.0f, downwardMotion);

        world.setContactListener(new ContactListener(){

            @Override
            public void beginContact(Contact contact) {
                System.out.println("Collision Detected");
            }

            @Override
            public void endContact(Contact contact) {}

            @Override
            public void preSolve(Contact contact, Manifold oldManifold) {}

            @Override
            public void postSolve(Contact contact, ContactImpulse impulse) {}
        });
    }

    @Override
    public void update(float delta) {
        world.step(0.033f, 8, 3);
    }

    @Override
    public void paint(float alpha) {}

    @Override
    public int updateRate() {
        return 25;
    }

    public void createPlayer(World world, float ix, float iy, float vx, float vy) {
        BodyDef def; FixtureDef head;
        def = new BodyDef();
            def.type = BodyType.DYNAMIC;
        def.position = new Vec2(ix, iy);
        def.linearVelocity = new Vec2(vx, vy);
        def.linearDamping = .3f;
        def.fixedRotation = true;

        head = new FixtureDef();
        head.filter.categoryBits = 1;
        head.filter.maskBits = 14;

        float pw = 1f;
        float ph = 2f;

        head.shape = new PolygonShape();
        ((PolygonShape)head.shape).set(
            new Vec2[]{
                new  Vec2(-pw/2f,-ph/2f),
                new  Vec2(pw/2f,-ph/2f),
                new  Vec2(pw/2f,ph/2f),
                new  Vec2(-pw/2.f,ph/2.f)}, 4);
        head.friction = 0.0f;
        head.density = 1.0f;

        body = world.createBody(def);
        body.createFixture(head);
        body.m_fixtureList.setUserData("head");
    }

    public void createBlock(World world, Shape[] v, float vx, float vy){
        float advanceTime = 0f;
        FixtureDef fixture;
        BodyDef body;
        body = new BodyDef();
        body.fixedRotation = true;
        body.type = BodyType.KINEMATIC;
        body.position = new Vec2(-advanceTime*vx, -advanceTime*vy);
        body.linearVelocity = new Vec2(vx, vy);

        Body object = world.createBody(body);
        for(Shape s : v) {
            fixture = new FixtureDef();
            fixture.shape = s;
            object.createFixture(createBlockFixture(fixture));
        }
    }

    public FixtureDef createBlockFixture(FixtureDef fixture){
        fixture.filter.categoryBits = 2;
        fixture.filter.maskBits = 1;
        fixture.isSensor = false;
        fixture.friction = .5f;
        return fixture;
    }

    public final Shape[] createPolygonShape(Vec2[][] v) {
        PolygonShape[] s = new PolygonShape[v.length];
        for(int p = 0; p < v.length; p++) {
            s[p] = new PolygonShape();
            s[p].set(v[p], v[p].length);
        }
        return s;
    }
}

Original issue reported on code.google.com by daniel.k...@thingobjectentity.net on 22 Sep 2012 at 6:53