Skip to content

Commit 8441526

Browse files
committed
Add sv_pushgrid and sv_analyticphysics cvars
1 parent f8067d5 commit 8441526

3 files changed

Lines changed: 41 additions & 11 deletions

File tree

Quake/sv_main.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,8 @@ void SV_Init (void)
11431143
extern cvar_t sv_gameplayfix_bouncedownslopes;
11441144
extern cvar_t sv_gameplayfix_elevators;
11451145
extern cvar_t sv_fastpushmove;
1146+
extern cvar_t sv_pushgrid;
1147+
extern cvar_t sv_analyticphysics;
11461148
extern cvar_t sv_friction;
11471149
extern cvar_t sv_edgefriction;
11481150
extern cvar_t sv_stopspeed;
@@ -1174,6 +1176,8 @@ void SV_Init (void)
11741176
Cvar_RegisterVariable (&sv_gameplayfix_bouncedownslopes);
11751177
Cvar_RegisterVariable (&sv_gameplayfix_elevators);
11761178
Cvar_RegisterVariable (&sv_fastpushmove);
1179+
Cvar_RegisterVariable (&sv_pushgrid);
1180+
Cvar_RegisterVariable (&sv_analyticphysics);
11771181
Cvar_RegisterVariable (&pr_checkextension);
11781182
Cvar_RegisterVariable (&sv_altnoclip); // johnfitz
11791183
Cvar_RegisterVariable (&sv_netsort);

Quake/sv_phys.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ cvar_t sv_freezenonclients = {"sv_freezenonclients", "0", CVAR_NONE};
5050
cvar_t sv_gameplayfix_spawnbeforethinks = {"sv_gameplayfix_spawnbeforethinks", "0", CVAR_NONE};
5151
cvar_t sv_gameplayfix_bouncedownslopes = {"sv_gameplayfix_bouncedownslopes", "1", CVAR_NONE}; // fixes grenades making horrible noises on slopes.
5252
cvar_t sv_fastpushmove = {"sv_fastpushmove", "1", CVAR_ARCHIVE}; // 0=old SV_PushMove processing; 1= faster SV_PushMove, (default)
53+
cvar_t sv_pushgrid = {"sv_pushgrid", "1", CVAR_NONE}; // cull SV_PushMove candidates with a spatial hash, needs sv_fastpushmove
54+
cvar_t sv_analyticphysics = {"sv_analyticphysics", "1", CVAR_NONE}; // gravity/friction integration matches 72Hz physics at any tick rate
55+
56+
qboolean sv_analyticphysics_frame = true; // sv_analyticphysics latched per SV_Physics, QC can flip the cvar mid-tick
5357

5458
#define MOVE_EPSILON 0.01
5559

@@ -83,8 +87,9 @@ static edict_t *push_grid_large[PUSH_GRID_MAX_LARGE];
8387
static int push_grid_num_large;
8488
static int push_grid_tail_start;
8589
static qboolean push_grid_valid;
86-
static qboolean push_grid_active; // inside SV_Physics with a built grid
87-
static qcvm_t *push_grid_qcvm; // vm the grid was built for, entities from other vms must not mix in
90+
static qboolean push_grid_active; // inside SV_Physics with a built grid
91+
static qboolean push_cache_active; // inside SV_Physics with a filled pushable cache
92+
static qcvm_t *push_grid_qcvm; // vm the grid was built for, entities from other vms must not mix in
8893

8994
static qboolean SV_IsPushable (edict_t *ent)
9095
{
@@ -630,11 +635,14 @@ zero when frametime == 1/72.
630635
*/
631636
static void SV_AddGravity (edict_t *ent)
632637
{
633-
ent->v.velocity[2] -= SV_EntGravity (ent) * sv_gravity.value * (host_frametime + 1.0 / MAX_PHYSICS_FREQ) * 0.5;
638+
const double dt = sv_analyticphysics_frame ? (host_frametime + 1.0 / MAX_PHYSICS_FREQ) * 0.5 : host_frametime;
639+
ent->v.velocity[2] -= SV_EntGravity (ent) * sv_gravity.value * dt;
634640
}
635641

636642
static void SV_FinishGravity (edict_t *ent)
637643
{
644+
if (!sv_analyticphysics_frame)
645+
return;
638646
// entities that landed during the move keep their clipped velocity, like at 72fps
639647
if ((int)ent->v.flags & FL_ONGROUND)
640648
return;
@@ -751,6 +759,11 @@ static void SV_PushMove (edict_t *pusher, float movetime)
751759
fast_count = num_pushable_ent_cache;
752760
}
753761
}
762+
else if (push_cache_active)
763+
{ // sv_pushgrid 0: scan the whole cache
764+
fast_list = pushable_ent_cache;
765+
fast_count = num_pushable_ent_cache;
766+
}
754767

755768
int e = -1;
756769

@@ -1618,8 +1631,10 @@ void SV_Physics (void)
16181631
else
16191632
entity_cap = qcvm->num_edicts;
16201633

1621-
// QC can flip the cvar mid-tick, the whole tick must use one consistent decision
1634+
// QC can flip the cvars mid-tick, the whole tick must use one consistent decision
16221635
const qboolean fast_pushers = (sv_fastpushmove.value > 0.f);
1636+
const qboolean use_push_grid = fast_pushers && (sv_pushgrid.value > 0.f);
1637+
sv_analyticphysics_frame = (sv_analyticphysics.value > 0.f);
16231638

16241639
// fill the pushable entities cache and the spatial grid over it
16251640
if (fast_pushers)
@@ -1629,7 +1644,8 @@ void SV_Physics (void)
16291644
build_start = Sys_DoubleTime ();
16301645

16311646
num_pushable_ent_cache = 0;
1632-
PushGrid_Clear ();
1647+
if (use_push_grid)
1648+
PushGrid_Clear ();
16331649
// beware, we skip entity 0 here:
16341650
edict_t *check = NEXT_EDICT (qcvm->edicts);
16351651
for (int e = 1; e < qcvm->num_edicts; e++, check = NEXT_EDICT (check))
@@ -1640,11 +1656,16 @@ void SV_Physics (void)
16401656
continue;
16411657

16421658
pushable_ent_cache[num_pushable_ent_cache++] = check;
1643-
PushGrid_Insert (check);
1659+
if (use_push_grid)
1660+
PushGrid_Insert (check);
16441661
}
16451662
push_grid_tail_start = num_pushable_ent_cache;
1646-
push_grid_qcvm = qcvm;
1647-
push_grid_active = true;
1663+
push_cache_active = true;
1664+
if (use_push_grid)
1665+
{
1666+
push_grid_qcvm = qcvm;
1667+
push_grid_active = true;
1668+
}
16481669

16491670
if (sv_speeds.value && qcvm == &sv.qcvm)
16501671
{
@@ -1715,6 +1736,7 @@ void SV_Physics (void)
17151736
if (fast_pushers)
17161737
{
17171738
push_grid_active = false;
1739+
push_cache_active = false;
17181740
ED_AllocSetHook (previous_alloc_hook);
17191741
}
17201742
}

Quake/sv_user.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,14 +147,16 @@ void SV_UserFriction (void)
147147
// apply friction, matching the canonical 72Hz decay for any frame duration:
148148
// exponential while speed is above stopspeed, then linear below it
149149
{
150+
extern qboolean sv_analyticphysics_frame;
151+
150152
const double tau = 1.0 / MAX_PHYSICS_FREQ;
151153
double s = host_frametime / tau;
152154
double r = 1.0 - friction * tau;
153155
double ns = speed;
154156

155-
if (r <= 0)
157+
if (!sv_analyticphysics_frame || r <= 0)
156158
{
157-
// degenerate friction values stop within one tick, keep the classic formula
159+
// classic frame-dependent formula; also for degenerate friction values that stop within one tick
158160
control = speed < sv_stopspeed.value ? sv_stopspeed.value : speed;
159161
ns = speed - host_frametime * control * friction;
160162
}
@@ -284,9 +286,11 @@ void SV_WaterMove (void)
284286
speed = VectorLength (velocity);
285287
if (speed)
286288
{
289+
extern qboolean sv_analyticphysics_frame;
290+
287291
const double tau = 1.0 / MAX_PHYSICS_FREQ;
288292
double r = 1.0 - sv_friction.value * tau;
289-
if (r <= 0)
293+
if (!sv_analyticphysics_frame || r <= 0)
290294
newspeed = speed - host_frametime * speed * sv_friction.value;
291295
else
292296
newspeed = speed * pow (r, host_frametime / tau);

0 commit comments

Comments
 (0)