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

Sleeping Bodies wont wake when applying force manually #1112

Open
clickstan opened this issue Apr 15, 2022 · 0 comments
Open

Sleeping Bodies wont wake when applying force manually #1112

clickstan opened this issue Apr 15, 2022 · 0 comments

Comments

@clickstan
Copy link

clickstan commented Apr 15, 2022

I've noticed a major issue when playing around with matter.js (when sleeping is enabled)- moving a body by manually applying forces seems to break the engine, causing sleeping bodies to not wake up anymore.

Live Demo of the broken sleeping: (within a few seconds, most bodies get stuck asleep, wont wake)
http://publicdemo-physics.gatarn.io/matter-js-example/
Screen Shot 2022-04-15 at 3 59 13 PM

Tick method code:
The issue shown in the demo happens if the "moveBigRectangles()" is put in any of these event callbacks.

Render.run(render);

// run the renderer
    Render.run(render);

    // create runner
    var runner = Runner.create({});

    Matter.Events.on(runner, "beforeUpdate", function (event) {
        moveBigRectangles(); //sleeping has issues
    });
    Matter.Events.on(runner, "afterUpdate", function (event) {

    });
    Matter.Events.on(runner, "beforeTick", function (event) {
    });
    Matter.Events.on(runner, "afterTick", function (event) {

    });
    Runner.run(runner, engine);

PS: As i was posting this example, it appears that this issue fixes when using the given Runner.run! What am I doing wrong in my tick method? When calling (Engine.update)

Works properly when using this tick method code:

    Render.run(render);
    // create runner
    var runner = Runner.create({});
    Runner.run(runner, engine);

    //custom engine tick
    function tick() {
        //apply forces every tick
        moveBigRectangles();
    }
    window.setInterval(tick, 1000 / 60);

Code run on the moving rectangles before every tick, to move them: (Just applies a force every tick)

function moveBigRectangles() {

        //apply force to all moving bodies
        for (var i = 0; i < movingBodies.length; i++) {
            var aBody = movingBodies[i];

            var force = 0.003;
            var deltaVector = Matter.Vector.sub({ x: aBody.goalX, y: aBody.goalY }, aBody.position);
            var normalizedDelta = Matter.Vector.normalise(deltaVector);
            var forceVector = Matter.Vector.mult(normalizedDelta, force);
            Matter.Body.applyForce(aBody, aBody.position, forceVector);
        }

Entire demo code:

``` // module aliases var Engine = Matter.Engine, Render = Matter.Render, Runner = Matter.Runner, Bodies = Matter.Bodies, Composite = Matter.Composite;
// create an engine
var engine = Engine.create({ enableSleeping: true });

engine.world.gravity.y = 0;//-0.005;
engine.world.gravity.x = 0;
// create a renderer
var render = Render.create({
    element: document.body,
    engine: engine,
    options: { showDebug: true, showPerformance: true }
});

//settings
let worldSize = 800.0;
let numMovingBodies = 3;
let numSmallBodies = 700;
let smallBodySize = worldSize / 50.0;
let movingBodySize = worldSize / 7.0;
let pad = worldSize * 0.05;

var canvas = render.canvas;
canvas.width = worldSize;
canvas.height = worldSize;


function setRandomMovePos(body) {
    //set move position of a moving body
    bodySize = body.bodySize;
    var x = (bodySize + pad) + Math.random() * (worldSize - (bodySize + pad) * 2);
    var y = (bodySize + pad) + Math.random() * (worldSize - (bodySize + pad) * 2);
    body.goalX = x;
    body.goalY = y;
    console.log("Changed goal pos");
}
nextTargetChangeTime = +new Date();
function moveBigRectangles() {

    //apply force to all moving bodies
    for (var i = 0; i < movingBodies.length; i++) {
        var aBody = movingBodies[i];

        var force = 0.003;
        var deltaVector = Matter.Vector.sub({ x: aBody.goalX, y: aBody.goalY }, aBody.position);
        var normalizedDelta = Matter.Vector.normalise(deltaVector);
        var forceVector = Matter.Vector.mult(normalizedDelta, force);
        Matter.Body.applyForce(aBody, aBody.position, forceVector);
    }

    //change target move pos every 2s
    var updatePos = (+new Date() > nextTargetChangeTime);
    if (updatePos) {
        nextTargetChangeTime = +new Date() + 2000;

        for (var i = 0; i < movingBodies.length; i++) {
            var aBody = movingBodies[i];
            setRandomMovePos(aBody);
        }
    }
}

//create ground

//bottom
var ground = Bodies.rectangle(worldSize / 2, worldSize - pad / 2, worldSize, pad, { isStatic: true });
Composite.add(engine.world, ground);
//top
var ground = Bodies.rectangle(worldSize / 2, pad / 2, worldSize, pad, { isStatic: true });
Composite.add(engine.world, ground);
//left
var ground = Bodies.rectangle(pad / 2, worldSize / 2, pad, worldSize, { isStatic: true });
Composite.add(engine.world, ground);
//right
var ground = Bodies.rectangle(worldSize - pad / 2, worldSize / 2, pad, worldSize, { isStatic: true });
Composite.add(engine.world, ground);

//create bodies
function addSmallBody() {
    var bodySize = smallBodySize;
    //place body randomly in the world
    var x = (bodySize + pad) + Math.random() * (worldSize - (bodySize + pad) * 2);
    var y = (bodySize + pad) + Math.random() * (worldSize - (bodySize + pad) * 2);

    var body = Bodies.rectangle(x, y, bodySize, bodySize / 2);
    Composite.add(engine.world, body);
}
var movingBodies = [];
function addMovingBody() {
    var bodySize = movingBodySize;
    //random pos in the world
    var x = (bodySize + pad) + Math.random() * (worldSize - (bodySize + pad) * 2);
    var y = (bodySize + pad) + Math.random() * (worldSize - (bodySize + pad) * 2);

    body = Bodies.rectangle(x, y, bodySize, bodySize / 2, { isStatic: false });
    Composite.add(engine.world, body);

    body.bodySize = bodySize;

    movingBodies.push(body);
    setRandomMovePos(body);
}

// add all of the bodies to the world
for (var i = 0; i < numSmallBodies; i++) {
    addSmallBody();
}
for (var i = 0; i < numMovingBodies; i++) {
    addMovingBody();
}

// run the renderer
Render.run(render);

// create runner
var runner = Runner.create({});

Matter.Events.on(runner, "beforeUpdate", function (event) {
    moveBigRectangles();
});
Matter.Events.on(runner, "afterUpdate", function (event) {

});
Matter.Events.on(runner, "beforeTick", function (event) {
   // moveBigRectangles();
});
Matter.Events.on(runner, "afterTick", function (event) {

});
Runner.run(runner, engine);

//custom run (everything works correctly)
function tick() {
    //moveBigRectangles();
}
window.setInterval(tick, 1000 / 60);
@clickstan clickstan changed the title Bodies not waking from sleep on collision- example included Bodies not waking from sleep on collision with custom run loop- example included Apr 15, 2022
@clickstan clickstan changed the title Bodies not waking from sleep on collision with custom run loop- example included Sleeping: Bodies not waking on collision with update loop- example included Apr 15, 2022
@clickstan clickstan changed the title Sleeping: Bodies not waking on collision with update loop- example included Sleeping Bodies waking breaks when manually applying forces on tick Apr 15, 2022
@clickstan clickstan changed the title Sleeping Bodies waking breaks when manually applying forces on tick Sleeping Bodies wont wake when using events Apr 15, 2022
@clickstan clickstan changed the title Sleeping Bodies wont wake when using events Sleeping Bodies wont wake when applying force during events Apr 15, 2022
@clickstan clickstan changed the title Sleeping Bodies wont wake when applying force during events Sleeping Bodies wont wake when applying force manually Apr 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants