2
\$\begingroup\$

I am trying to rotate a model with inertia damping with the keyboard. The code works great with a fixed time step but it doesn't behave the same with a variable update frequency.

Update method:

protected override void Update(GameTime gameTime)
{
    base.Update(gameTime);

    float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
    const float rotationPerSecond = 0.25f;
    const float decayPerSecond = 0.5f;

    KeyboardState kb = Keyboard.GetState();

    if (kb.IsKeyDown(Keys.Left))
    {
        m_velocity += rotationPerSecond * elapsed;
    }
    else if (kb.IsKeyDown(Keys.Right))
    {
        m_velocity -= rotationPerSecond * elapsed;
    }
    else
    {
        if (Math.Abs(m_velocity) < 0.01f)
        {
            m_velocity = 0;
        }
        else if (m_velocity > 0)
        {
            m_velocity -= decayPerSecond * elapsed;
        }
        else if (m_velocity < 0)
        {
            m_velocity += decayPerSecond * elapsed;
        }
    }

    m_rotationAngle += m_velocity;
}  

Draw method:

Matrix rot = Matrix.CreateWorld(new Vector3(0, 0, 0), Vector3.Forward, Vector3.Up) * 
                         Matrix.CreateRotationY(MathHelper.ToRadians(m_rotationAngle));

I am changing the time step with

IsFixedTimeStep = true;
graphics.SynchronizeWithVerticalRetrace = true;

and

IsFixedTimeStep = false;
graphics.SynchronizeWithVerticalRetrace = false;

Rotation speed and damping is completely different with different update frequencies. Any ideas what i am doing wrong? i have timed the code with a stopwatch, and it does work ok if you fake the keyboard input to be always on (remove the keyboard if()) and just do:

m_velocity += rotationPerSecond * elapsed;

Full Solution can be found here testproject

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.