schteppe / p2.js

JavaScript 2D physics library
Other
2.64k stars 330 forks source link

Ball has more momentum than conservation #258

Closed lcsweet closed 7 years ago

lcsweet commented 7 years ago

I put all the forces of the physical world are removed, the interval 100 ms to create a ball, to create a total of 50 teeth, the ball and the wall a few times after the collision angle of reflection and speed some ball has changed several times, the beginning of the collision is correct. With a version of the v0.7.1 p2.js, if you can download the EgretEngine run Demo. download address: http://tool.egret-labs.org/EgretEngine/EgretEngine-v3.1.8.exe?time=1473127114 and http://tool.egret-labs.org/EgretWing/electron/EgretWing-v3.1.8.exe?time=1473127214. EgretEngine's official website is:http://egret.com/

The setting of this world is:

    //创建world
    this.world = new p2.World();
    //set p2.world.sleepMode
    this.world.sleepMode = p2.World.NO_SLEEPING;
    this.world.applyDamping = false;
    this.world.applyGravity = false;  
    this.world.frictionGravity = 0;
    this.world.applySpringForces = false;

The setting of the ball is:

    var body: p2.Body = new p2.Body({ mass: 3, position: [p2x, p2y],velocity: [-this.speed * Math.sin(angle),       this.speed * Math.cos(angle)] });
    body.type = type;
    body.angularDamping = 0;
    body.angularForce = 0;
    body.applyDamping(0);
    body.allowSleep = true;
    body.damping = 0;
    body.addShape(bodyShape);//给刚体添加p2.Shape
    p2World.addBody(body);

The four sides of the wall is set up:

    var body: p2.Body = new p2.Body({ mass: 1, position: [p2x, p2y]});
    body.type = type;
    body.angularDamping = 0;
    body.angularForce = 0;
    body.applyDamping(0);
    body.allowSleep = false;
    body.damping = 0;
    body.addShape(bodyShape);//给刚体添加p2.Shape
    p2World.addBody(body);

The collision material between the ball and the wall is set up:

    var mtl1: p2.Material = new p2.Material(1000); //The ball
    var mtl2: p2.Material = new p2.Material(1001); //The four sides
    var cmtl: p2.ContactMaterial = new p2.ContactMaterial(mtl1, mtl2, <p2.ContactMaterialOptions>{ restitution: 1.0,  friction: 0 });
    this.world.addContactMaterial(cmtl);

I recorded a video of a ball. http://www.xchang-cq.com/demo/demo.MP4 The demo url: http://www.xchang-cq.com/demo/P2Test.zip

schteppe commented 7 years ago

I don't understand the problem... I don't have a windows machine at the moment, so I cannot run your executables. And the links don't seem to work either...

The main problem, is it circle/plane collisions? When restitution=1 and friction=0?

lcsweet commented 7 years ago

The main problem, is it circle/box collisions,The angular velocity and reflection angle of the circle and box collision can be transmitted.

Sorry, the last link to the problem.

The EgretEngine download address: http://tool.egret-labs.org/EgretEngine/EgretEngine-v3.1.8.dmg?time=1473218023 and http://egret.com/api/download/index?app=EgretWing&v=3.1.8&f=product. EgretEngine's official website is:http://egret.com/

I recorded a video of a ball. http://www.xchange-cq.com/demo/demo.MP4 The demo url: http://www.xchange-cq.com/demo/P2Test.zip

schteppe commented 7 years ago

Oh that's strange... Maybe it's because the ball is touching the corner somehow. Really hard to see in the video.

Another thing I notice is that you run your simulation with a variable time step. If you get a large time step, a lot of things could go wrong!

    //update step
    protected p2RunStep(dt) {
        if (dt < 10) {
            return;
        }
        if (dt > 1000) {
            return;
        }

        this.world.step(dt / 1000);//p2.World.step                                 
        this.updateWorldBodiesSkin(this.world);//更新p2World内所有刚体皮肤显示

    }

If you change the world.step part to the following, it should be more safe:

 this.world.step(1 / 60, dt / 1000, 5);//p2.World.step             

(using fixedTimeStep = 1/60 and maxSubSteps=5, you may want to tweak these)

Try it and see if it gets better!

lcsweet commented 7 years ago

After changing the world.step part of the situation is not improved, at the beginning of the speed up the greater the probability of the emergence of BUG

schteppe commented 7 years ago

Interesting. Ok so next step is to reconstruct the scene as a demo in the demos/ directory, for easier debugging.

There's probably something wrong with the way the impact restitution is applied, maybe because the ball is touching two walls at the same time... Will have to look closer to find out.

lcsweet commented 7 years ago

Continuous impact on the same point will appear Bug, see demo:

http://www.xchange-cq.com/demo/demo1.MP4

schteppe commented 7 years ago

Not sure if this solves it, but try setting .contactSkinSize=0 on your ContactMaterial?

lcsweet commented 7 years ago

This setting does not seem to work, contactSkinSize=0

   var cmtl: p2.ContactMaterial = new p2.ContactMaterial(mtl1, mtl2, <p2.ContactMaterialOptions>{ restitution: 1.0,  friction: 0 });
    var cmt2: p2.ContactMaterial = new p2.ContactMaterial(mtl1, mtl3, <p2.ContactMaterialOptions>{ restitution: 1.0, friction: 0 });
    cmtl.contactSkinSize = 0;
    cmt2.contactSkinSize = 0;
    this.world.addContactMaterial(cmtl);
    this.world.addContactMaterial(cmt2);
schteppe commented 7 years ago

I think I found it ... you change the body.id property in your code. This surely messes up the lookup of contact state, and maybe other things as well. Please avoid this and let me know how it goes.

lcsweet commented 7 years ago

This body.id is not set on the right, I can not set the body.id?

schteppe commented 7 years ago

The id property is used internally in p2 and it's safest to not touch it. If you still want to use it, you need to make sure all bodies in a World have unique id's and not change the id during simulation.

"Not set on the right" - I'm not sure what you mean there?

lcsweet commented 7 years ago

It's normal to not set the body.id ball collision. Thank you very much for your help.

schteppe commented 7 years ago

Great! I'm glad it was resolved.