Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

matter.js - monitor affects the engine physics

everything is constant but moving the chrome tab to another monitor affects in some way on the physics of the dropping ball

video of the issue: (recorded on a mac) https://www.youtube.com/watch?v=eNoVshieh08

as I understand the engine pixelRatio is defined as 1:1, meaning a larger/smaller screen with different resolution shouldn't change the behavior of the ball's physics.

In addition it seems that the leftmost monitor has always the same expected behavior (the ball drops from 1 point goes through the same peg route and reaches the exact end location.

My other monitors, the middle one (which has the biggest resolution) and the right one which is the macbook retina display cause the ball to drop and change it's route from time to time.

UPDATE

changing the mid monitor to have the same resolution and refresh rate made the ball behave in exactly the same way. so now the question is why the refresh rate changes the behavior of the engine physics and how can we control it?

Engine Creation:

      // create an this.engine
      this.engine = Engine.create()

      // create a renderer
      this.render = Render.create({
        element: this.$refs.scene,
        engine: this.engine,
        options: {
          wireframes: true,
          showAngleIndicator: true,
          showBroadphase: false,
          showBounds: true,
          // pixelRatio: 'auto',
          background: 'transparent',
          width: DEFS.WIDTH,
          height: 930,
        },
      })

Pegs Creation:

      // Create a generic peg object
      const peg = (x, y) => {
        return Bodies.circle(x, y, DEFS.PEGS.RADIUS, {
          isStatic: true,
          collisionFilter: {
            category: this.collisionCategories.default,
          },
          friction: 0,
          frictionAir: 0,
          frictionStatic: 0,
          restitution: 0,
          render: {
            fillStyle: 'lightblue',
            /* sprite: {
              texture: require('~/assets/wall-pin.png'),
              xScale: DEFS.PEGS.SCALE,
              yScale: DEFS.PEGS.SCALE,
            }, */
          },
        })
      }

Ball Creation:

      Bodies.circle(350, DEFS.DROPPER.Y + 20, DEFS.BALL.RADIUS, {
        density: 0.01,
        friction: 0.1,
        frictionAir: 0,
        frictionStatic: 0,
        restitution: 0.3,
        collisionFilter: {
          category: this.collisionCategories.ball,
          mask: this.collisionCategories.default,
        },
        render: {
          fillStyle: 'lightblue',
          /* sprite: {
            texture: require('~/assets/ball.png'),
            xScale: DEFS.BALL.SCALE,
            yScale: DEFS.BALL.SCALE,
          }, */
        },
      })
like image 719
Ehud Shahak Avatar asked Sep 17 '25 00:09

Ehud Shahak


1 Answers

Ok, so the problem was the different refresh rate that each monitor has In conjunction with how the Runner class handles identifying a changing refresh rate and requestAnimationFrame calls. TLDR:

Runner.create({
  isFixed: true,
})

In more details: https://brm.io/matter-js/docs/classes/Runner.html#property_isFixed

Runner.toFixed specifies if the runner should use a fixed timestep (otherwise it is variable). If timing is fixed, then the apparent simulation speed will change depending on the frame rate (but behaviour will be deterministic). If the timing is variable, then the apparent simulation speed will be constant (approximately, but at the cost of determininism).

Default: false

Also a good explanation is: https://gafferongames.com/post/fix_your_timestep/

like image 193
Ehud Shahak Avatar answered Sep 19 '25 15:09

Ehud Shahak