*>Sss |
*>Sss |
Line 1: |
Line 1: |
| QW physics: moving in air, bunnyhop. | | QW physics: moving in air, bunnyhop. |
− | !!!!!!!Article is not correct at the moment. It will be fixed soon!!!
| |
| | | |
| With commands | | With commands |
Line 13: |
Line 12: |
| | | |
| | | |
− | Those values are defined by variables
| + | //TODO |
− | cl_sidespeed, cl_forwardspeed, cl_backspeed, cl_upspeed.
| |
− | | |
− | | |
− | Also command +speed increases them 2 times.
| |
− | | |
− | If 2 opposite commands are (for example +forward and +back) then only earliest is really active.
| |
− | | |
− | Valuses forwardmove, sidemove, upmove are sent to server and
| |
− | also used in client to predict movement.
| |
− | | |
− | Code that processes player movement must be equal in client and server.
| |
− | | |
− | For example I have
| |
− | cl_forwardspeed 400 (ezquake default) and
| |
− | also there is following line in my config which is executed at the client start:
| |
− | +mlook;wait;+speed;wait;
| |
− | | |
− | Thus when pressing +forward
| |
− | forwardmove = 2 * 400 = 800.
| |
− | | |
− | | |
− | Movement of layers is processed in function PM_PlayerMove.
| |
− | | |
− | | |
− | Probably to reduce traffic quake clients remove several bits and
| |
− | forwardmove = 800 become 508 в PM_PlayerMove.
| |
− | | |
− | | |
− | Lets see player movement in air.
| |
− | So called vector of wished speed is calculated.
| |
− | In air it is horizontal and is summed up from 2 components:
| |
− | horyzontal vector with length forwardmove wich is directed along player view but horizontally
| |
− | and of vector with length sidemove which is horizontal and perpendicular to 1st component.
| |
− | | |
− | | |
− | (Need picture.)
| |
− | | |
− | upmove is not used while in air. Only gravitation affects player movement in air.
| |
− | | |
− | Next , if length of received vector of wishspeed is grater than server restriction
| |
− | its length is decreased to meet restrictions.
| |
− | | |
− | This length is 320 for usual TDM and
| |
− | changes from 230 to 450 depending on player class in TF.
| |
− | | |
− | | |
− | Next step. We are in function PM_PlayerAccelerate() and
| |
− | we have vector of wished direction with length 1
| |
− | and value of wished speed.
| |
− | | |
− | First of all value of wished speed is restricted by 30:
| |
− | wishspd = min(wishspd, 30);
| |
− | | |
− | Then value of projection of current velocity to wished direction is calculated:
| |
− | currentspeed = DotProduct (pmove.velocity, wishdir);
| |
− | | |
− | Вычисляем разницу между желаемой скоростью и проекцией теущей скорости.
| |
− | Then difference between wished speed and projection of current velocity
| |
− | is calculated. If result is not positive then velocity does not change.
| |
− | | |
− | addspeed = wishspd - currentspeed;
| |
− | if (addspeed <= 0)
| |
− | return;
| |
− | | |
− | | |
− | Then calculated value
| |
− | accelspeed = accel * wishspeed * pm_frametime =
| |
− | 10 *320 * 0.014 = 44.8.
| |
− | (wishspeed - is not wishspd here)
| |
− | | |
− | Then minimal value between is taken:
| |
− | accelspeed = min(accelspeed, addspeed);
| |
− | | |
− | Final step: vector with length accelspeed and direction wishdir is added to current velocity.
| |
− | VectorMA(pmove.velocity, accelspeed, wishdir, pmove.velocity);
| |
− | | |
− | | |
− | Simpliest cases.
| |
− | If player is in air and does not press buttons his horizontal speed does not change.
| |
− | | |
− | If player has zero speed pressin +forward gives him speed 30 directed horizontally forward.
| |
− | | |
− | Now we can look into bunnyhop.
| |
− | Wewill concider speed greater than server restriction (320 in TDM)
| |
− | because player can gain that speed while he is on ground.
| |
− | | |
− | And of course we concder that player does not set too small values of
| |
− | cl_sidespeed, cl_forwardspeed, cl_backspeed.
| |
− | | |
− | Nice fact about QW is that it does not matter where player looking to.
| |
− | Only his wishdir is important.
| |
− | | |
− | | |
− | Let angle between horizontal velocity v и wishdir is gamma.
| |
− | | |
− | wishspd = min(wishspd, 30) = 30 with conditions given above.
| |
− | | |
− | addspeed = wishspd - currentspeed = 30 - v * cos(gamma)
| |
− | | |
− | Final value of accelspeed >=0.
| |
− | | |
− | When bunnyhopping we want to increase speed so we must have
| |
− | | |
− | cos(gamma) > 0
| |
− | addspeed = 30 - v * cos(gamma) > 0
| |
− | | |
− | When bunnyhopping value accel * wishspeed * pm_frametime is not important.
| |
− | Really 44.8 > 30 - v * cos(gamma) if cos(gamma) > -14.8/v
| |
− | that is only if we are decaccelerating.
| |
− | | |
− | So when bunnyhopping we have accelspeed = addspeed;
| |
− | | |
− | | |
− | Increase of speed in one frame is
| |
− | dv_frame = addspeed * cos(gamma) = (30 - v * cos(gamma)) * cos(gamma).
| |
− | | |
− | Graphic of dv_frame(cos(gamma)) is parabola
| |
− | | |
− | | |
− | (Need picture)
| |
− | Upper (best) point is when соs(gamma_best) = 15 / v;
| |
− | | |
− | Best possible increase in one frame is
| |
− | dv_frame_best = (30 - v * 15 / v) * 15 / v = 225 / v.
| |
− | | |
− | pm_frametime = 0.013, if 77fps phisics is active
| |
− | and pm_frametime = 0.014, if 72fps phisics (TF2003 standard, old TDM standard).
| |
− | | |
− | Ultimately speed increase is described by following differential equation:
| |
− | dv/dt = 225/(v * pm_frametime)
| |
− | | |
− | | |
− | Acceleration with 77fps phisics is about 7% bigger than with 72fps.
| |
− | | |
− | | |
− | v(t) ~ sqrt(t - t0).
| |
− | | |
− | | |
− | | |
− | Theoretically speed of 2000 can be reached within 111 seconds with 77fps phisics.
| |
− | It was experimentally proved that player can overcome sv_maxvelocity which is by default.
| |
− | | |
− | Player must keep best direction of wishdir.
| |
− | He rotates to make it.
| |
− | | |
− | Player can look up or down while bunnyhopping: it does not matter for physics.
| |
− | | |
− | Correct angle speed is
| |
− | omega = addspeed * sin(gamma) / v = (15 / v) * sqrt(1 - (15 / v)^2).
| |
− | | |
− | So the greater is speed the less is best angle speed.
| |
− | | |
− | Comments and corrections are welcome.
| |