Math

Metareal has some objects that just stay in one place and rotate. They look nice.

Came across a funny little bug this morning. I’d let Metareal run all night, and the rotating objects were all moving a bit chunkily, not turning smoothly like they should.

Frame rate: AOK, 60 FPS still rock solid.
Player movement: AOK, nice and smooth.
Spinning objects: All of them kikk’ty kikk’ty kich. Broke!

Took a look at the rotating object code. Each game objects has a “body” and a “mind”, spinning is implemented in a mind…
The “rotate” parameter is a vec4 as {axisX, axisY, axisZ, degreesPerSecond}.

bool SpinMind::mindTick() override
{
  MOVEC4(rotate); // retrieve instance parameter "rotate" to local variable.
  this->tix++;
  float degrees = rotate[3] * tix / 60.0;
  rotate.v[3] = degrees;
  this->setBodyRotation(rotate, degrees);
        
  return true;
}

Can you spot the bug?

It’s roundoff error. As “tix” (ticks, ha ha) gets large, degrees gets large. Then degrees loses precision after running a while.

The solution? Accumulate degree (not ticks), and wrap at +/-360.

bool SpinMind::mindTick() override
{
  MOVEC4(rotate);
  this->degrees = fmod(this->degrees + rotate[3] / 60.0, 360.0);
  rotate.v[3] = this->degrees;
  this->setBodyRotation(rotate, degrees);
        
  return true;
}

This is all basic and obvious! But apparently I got something working just enough, and moved onward. That’s the way to make progress.

Leave a Reply

Your email address will not be published.