@@ -50,6 +50,10 @@ cvar_t sv_freezenonclients = {"sv_freezenonclients", "0", CVAR_NONE};
5050cvar_t sv_gameplayfix_spawnbeforethinks = {"sv_gameplayfix_spawnbeforethinks" , "0" , CVAR_NONE };
5151cvar_t sv_gameplayfix_bouncedownslopes = {"sv_gameplayfix_bouncedownslopes" , "1" , CVAR_NONE }; // fixes grenades making horrible noises on slopes.
5252cvar_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];
8387static int push_grid_num_large ;
8488static int push_grid_tail_start ;
8589static 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
8994static qboolean SV_IsPushable (edict_t * ent )
9095{
@@ -630,11 +635,14 @@ zero when frametime == 1/72.
630635*/
631636static 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
636642static 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}
0 commit comments