From b340de8dfe7a16e38bccf8aef7a530061ce72902 Mon Sep 17 00:00:00 2001 From: TimePath Date: Fri, 24 Jun 2016 19:07:34 +1000 Subject: [PATCH] Move PM_walk to ecs --- qcsrc/common/physics/player.qc | 75 -------------------------- qcsrc/ecs/components/physics.qh | 2 + qcsrc/ecs/systems/physics.qc | 93 +++++++++++++++++++++++++++------ qcsrc/lib/vector.qh | 7 +++ 4 files changed, 86 insertions(+), 91 deletions(-) diff --git a/qcsrc/common/physics/player.qc b/qcsrc/common/physics/player.qc index 13a4bcd7a0..d1562dff12 100644 --- a/qcsrc/common/physics/player.qc +++ b/qcsrc/common/physics/player.qc @@ -1040,81 +1040,6 @@ void PM_jetpack(entity this, float maxspd_mod) #endif } -void PM_walk(entity this, float maxspd_mod) -{ - // walking - makevectors(this.v_angle.y * '0 1 0'); - const vector wishvel = v_forward * this.movement.x - + v_right * this.movement.y; - // acceleration - const vector wishdir = normalize(wishvel); - float wishspeed = vlen(wishvel); - wishspeed = min(wishspeed, PHYS_MAXSPEED(this) * maxspd_mod); - if (IS_DUCKED(this)) wishspeed *= 0.5; - - // apply edge friction - const float f2 = vlen2(vec2(this.velocity)); - if (f2 > 0) - { - trace_dphitq3surfaceflags = 0; - tracebox(this.origin, this.mins, this.maxs, this.origin - '0 0 1', MOVE_NOMONSTERS, this); - // TODO: apply edge friction - // apply ground friction - const int realfriction = (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK) - ? PHYS_FRICTION_SLICK(this) - : PHYS_FRICTION(this); - - float f = sqrt(f2); - f = 1 - PHYS_INPUT_TIMELENGTH * realfriction * ((f < PHYS_STOPSPEED(this)) ? (PHYS_STOPSPEED(this) / f) : 1); - f = max(0, f); - this.velocity *= f; - /* - Mathematical analysis time! - - Our goal is to invert this mess. - - For the two cases we get: - v = v0 * (1 - PHYS_INPUT_TIMELENGTH * (PHYS_STOPSPEED(this) / v0) * PHYS_FRICTION(this)) - = v0 - PHYS_INPUT_TIMELENGTH * PHYS_STOPSPEED(this) * PHYS_FRICTION(this) - v0 = v + PHYS_INPUT_TIMELENGTH * PHYS_STOPSPEED(this) * PHYS_FRICTION(this) - and - v = v0 * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this)) - v0 = v / (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this)) - - These cases would be chosen ONLY if: - v0 < PHYS_STOPSPEED(this) - v + PHYS_INPUT_TIMELENGTH * PHYS_STOPSPEED(this) * PHYS_FRICTION(this) < PHYS_STOPSPEED(this) - v < PHYS_STOPSPEED(this) * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this)) - and, respectively: - v0 >= PHYS_STOPSPEED(this) - v / (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this)) >= PHYS_STOPSPEED(this) - v >= PHYS_STOPSPEED(this) * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this)) - */ - } - const float addspeed = wishspeed - this.velocity * wishdir; - if (addspeed > 0) - { - const float accelspeed = min(PHYS_ACCELERATE(this) * PHYS_INPUT_TIMELENGTH * wishspeed, addspeed); - this.velocity += accelspeed * wishdir; - } -#ifdef CSQC - float g = PHYS_GRAVITY(this) * PHYS_ENTGRAVITY(this) * PHYS_INPUT_TIMELENGTH; - if(autocvar_cl_movement == 3) - { - if (!(GAMEPLAYFIX_NOGRAVITYONGROUND)) - this.velocity_z -= g * (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE ? 0.5 : 1); - } - if (vdist(this.velocity, >, 0)) - PM_ClientMovement_Move(this); - if(autocvar_cl_movement == 3) - { - if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE) - if (!IS_ONGROUND(this) || !GAMEPLAYFIX_NOGRAVITYONGROUND) - this.velocity_z -= g * 0.5; - } -#endif -} - void PM_air(entity this, float buttons_prev, float maxspd_mod) { makevectors(this.v_angle.y * '0 1 0'); diff --git a/qcsrc/ecs/components/physics.qh b/qcsrc/ecs/components/physics.qh index f3af010413..921907fe84 100644 --- a/qcsrc/ecs/components/physics.qh +++ b/qcsrc/ecs/components/physics.qh @@ -11,4 +11,6 @@ COMPONENT(phys); .vector com_phys_gravity; // TODO: remove +.bool com_phys_ground; .bool com_phys_ladder; +.bool com_phys_vel_2d; diff --git a/qcsrc/ecs/systems/physics.qc b/qcsrc/ecs/systems/physics.qc index c299079ef6..8a07efa83f 100644 --- a/qcsrc/ecs/systems/physics.qc +++ b/qcsrc/ecs/systems/physics.qc @@ -111,7 +111,15 @@ void sys_phys_update(entity this, float dt) this.velocity *= (1 - PHYS_FRICTION_ONLAND(this)); } } - PM_walk(this, maxspeed_mod); + this.com_phys_vel_max = PHYS_MAXSPEED(this) * maxspeed_mod; + this.com_phys_gravity = '0 0 -1' * PHYS_GRAVITY(this) * dt; + if (PHYS_ENTGRAVITY(this)) { this.com_phys_gravity *= PHYS_ENTGRAVITY(this); } + this.com_phys_ground = true; + this.com_phys_vel_2d = true; + sys_phys_simulate(this, dt); + this.com_phys_vel_2d = false; + this.com_phys_ground = false; + this.com_phys_gravity = '0 0 0'; } else { PM_air(this, buttons_prev, maxspeed_mod); } @@ -127,25 +135,24 @@ void sys_phys_update(entity this, float dt) void sys_phys_simulate(entity this, float dt) { - // noclipping - // flying - // on a spawnfunc_func_ladder - // swimming in spawnfunc_func_water - UNSET_ONGROUND(this); - - float g = -this.com_phys_gravity.z; - if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE) { - g *= 0.5; - this.velocity_z += g; + const float g = -this.com_phys_gravity.z; + if (!this.com_phys_ground) { + // noclipping + // flying + // on a spawnfunc_func_ladder + // swimming in spawnfunc_func_water + UNSET_ONGROUND(this); + + this.velocity_z += g / 2; + this.velocity = this.velocity * (1 - dt * this.com_phys_friction); + this.velocity_z += g / 2; } - this.velocity = this.velocity * (1 - dt * this.com_phys_friction); - this.velocity_z += g; - makevectors(this.v_angle); + makevectors(vmul(this.v_angle, (this.com_phys_vel_2d ? '0 1 0' : '1 1 1'))); // wishvel = v_forward * this.movement.x + v_right * this.movement.y + v_up * this.movement.z; vector wishvel = v_forward * this.movement.x + v_right * this.movement.y - + '0 0 1' * this.movement.z; + + '0 0 1' * this.movement.z * (this.com_phys_vel_2d ? 0 : 1); if (this.com_phys_ladder) { if (this.viewloc) { wishvel.z = this.oldmovement.x; @@ -171,8 +178,62 @@ void sys_phys_simulate(entity this, float dt) } } // acceleration - vector wishdir = normalize(wishvel); + const vector wishdir = normalize(wishvel); float wishspeed = min(vlen(wishvel), this.com_phys_vel_max); + + if (this.com_phys_ground) { + if (IS_DUCKED(this)) { wishspeed *= 0.5; } + + // apply edge friction + const float f2 = vlen2(vec2(this.velocity)); + if (f2 > 0) { + trace_dphitq3surfaceflags = 0; + tracebox(this.origin, this.mins, this.maxs, this.origin - '0 0 1', MOVE_NOMONSTERS, this); + // TODO: apply edge friction + // apply ground friction + const int realfriction = (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK) + ? PHYS_FRICTION_SLICK(this) + : PHYS_FRICTION(this); + + float f = sqrt(f2); + f = 1 - PHYS_INPUT_TIMELENGTH * realfriction + * ((f < PHYS_STOPSPEED(this)) ? (PHYS_STOPSPEED(this) / f) : 1); + f = max(0, f); + this.velocity *= f; + /* + Mathematical analysis time! + + Our goal is to invert this mess. + + For the two cases we get: + v = v0 * (1 - PHYS_INPUT_TIMELENGTH * (PHYS_STOPSPEED(this) / v0) * PHYS_FRICTION(this)) + = v0 - PHYS_INPUT_TIMELENGTH * PHYS_STOPSPEED(this) * PHYS_FRICTION(this) + v0 = v + PHYS_INPUT_TIMELENGTH * PHYS_STOPSPEED(this) * PHYS_FRICTION(this) + and + v = v0 * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this)) + v0 = v / (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this)) + + These cases would be chosen ONLY if: + v0 < PHYS_STOPSPEED(this) + v + PHYS_INPUT_TIMELENGTH * PHYS_STOPSPEED(this) * PHYS_FRICTION(this) < PHYS_STOPSPEED(this) + v < PHYS_STOPSPEED(this) * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this)) + and, respectively: + v0 >= PHYS_STOPSPEED(this) + v / (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this)) >= PHYS_STOPSPEED(this) + v >= PHYS_STOPSPEED(this) * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this)) + */ + } + const float addspeed = wishspeed - this.velocity * wishdir; + if (addspeed > 0) { + const float accelspeed = min(PHYS_ACCELERATE(this) * PHYS_INPUT_TIMELENGTH * wishspeed, addspeed); + this.velocity += accelspeed * wishdir; + } + if (IS_CSQC && vdist(this.velocity, >, 0)) { + PM_ClientMovement_Move(this); + } + return; + } + if (IS_CSQC || time >= PHYS_TELEPORT_TIME(this)) { PM_Accelerate(this, wishdir, wishspeed, wishspeed, this.com_phys_acc_rate, 1, 0, 0, 0); } diff --git a/qcsrc/lib/vector.qh b/qcsrc/lib/vector.qh index adb6d6a95b..98b15115c8 100644 --- a/qcsrc/lib/vector.qh +++ b/qcsrc/lib/vector.qh @@ -34,6 +34,13 @@ vector cross(vector a, vector b) } #endif +noref vector _vmul_a, _vmul_b; +#define vmul(a, b) \ + (_vmul_a = (a), _vmul_b = (b), \ + '1 0 0' * (_vmul_a.x * _vmul_b.x) \ + + '0 1 0' * (_vmul_a.y * _vmul_b.y) \ + + '0 0 1' * (_vmul_a.z * _vmul_b.z)) + const vector eX = '1 0 0'; const vector eY = '0 1 0'; const vector eZ = '0 0 1'; -- 2.39.2