c++physicsgame-development

Source engine - Acceleration formula


I was going through the player movement code for the source engine when I stumbled upon the following function:

void CGameMovement::Accelerate( Vector& wishdir, float wishspeed, float accel )
    {
        int i;
        float addspeed, accelspeed, currentspeed;

        // This gets overridden because some games (CSPort) want to allow dead (observer) players
        // to be able to move around.
        if ( !CanAccelerate() )
            return;

        // See if we are changing direction a bit
        currentspeed = mv->m_vecVelocity.Dot(wishdir);

        // Reduce wishspeed by the amount of veer.
        addspeed = wishspeed - currentspeed;

        // If not going to add any speed, done.
        if (addspeed <= 0)
            return;

        // Determine amount of accleration.
        accelspeed = accel * gpGlobals->frametime * wishspeed * player->m_surfaceFriction;

        // Cap at addspeed
        if (accelspeed > addspeed)
            accelspeed = addspeed;
        
        // Adjust velocity.
        for (i=0 ; i<3 ; i++)
        {
            mv->m_vecVelocity[i] += accelspeed * wishdir[i];    
        }
    }

Although I do understand the concept of utilising the wishdir & wishspeed to calculate the velocity increment, I cannot figure out why they use the wishspeed and m_surfaceFriction in the calculation of accelspeed:

accelspeed = accel * gpGlobals->frametime * wishspeed * player->m_surfaceFriction;

I think it somehow compensates for the reduction in velocity due to friction that was calculated earlier, but multiplying these two variables with accel * gpGlobals->frametime does not seem to make physical sense.

Would somebody be able to explain the thoughts behind this calculation and why this extra wishspeed * player->m_surfaceFriction factor is applied to the accelspeed?


Solution

  • My Interpretation

    I think author make wishspeed simply act as scaler for accel, so the speed of currentspeed reach the wishspeed linear correlated to magnitude of the wishspeed, thus make sure the time required for currentspeed reach the wishspeed is approximately the same for different wishspeed if other parameters stay the same.

    And reason above that is because this could create some sort of urgent and relaxing effects which author desired for character's movement, i.e when speed we wish for character is big(small) then character's acceleration is also big(small), no matter sprint or jog, speed change well be finished in roughly same time period.

    And player->m_surfaceFriction is even more obvious, author just want an easy(linear) way to let surface friction value affect player's acceleration.

    Some advice

    From my own experience, when trying to understand the math related mechanism inside the realm of game development, especially physics or shader, we should focus more on the end effect or user experience the author trying to create instead of the mathematical rigor of the formula.

    We shouldn't trap ourselves with question like: is this formula real? or the formula make any physical sense?

    Well, if you look and any source code of physics simulation engine, you'll find out most of them if not all of them does not using real life formula, instead they rely on bunch of mathematical tricks to create the end effect that mimic our expectation of real life physics.

    E.g, PBD or XPBD one of the most widely used algorithm for cloth or softbody simulation, as name suggest, is position based dynamic, meaning they modify the particle's position explicitly, not as one may expected in a implicit way like in real life (force effect velocity then effect position), why do we using algorithm like this? because it create the visual effect match our expectation better.