Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SV_Physics() : Performance boost for SV_PushMove() when there is a lot of pushers and pushed entities. #731

Merged
merged 1 commit into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Quake/sv_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1136,6 +1136,7 @@ void SV_Init (void)
extern cvar_t sv_gameplayfix_spawnbeforethinks;
extern cvar_t sv_gameplayfix_bouncedownslopes;
extern cvar_t sv_gameplayfix_elevators;
extern cvar_t sv_fastpushmove;
extern cvar_t sv_friction;
extern cvar_t sv_edgefriction;
extern cvar_t sv_stopspeed;
Expand All @@ -1162,6 +1163,7 @@ void SV_Init (void)
Cvar_RegisterVariable (&sv_gameplayfix_spawnbeforethinks);
Cvar_RegisterVariable (&sv_gameplayfix_bouncedownslopes);
Cvar_RegisterVariable (&sv_gameplayfix_elevators);
Cvar_RegisterVariable (&sv_fastpushmove);
Cvar_RegisterVariable (&pr_checkextension);
Cvar_RegisterVariable (&sv_altnoclip); // johnfitz
Cvar_RegisterVariable (&sv_netsort);
Expand Down
50 changes: 47 additions & 3 deletions Quake/sv_phys.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ cvar_t sv_nostep = {"sv_nostep", "0", CVAR_NONE};
cvar_t sv_freezenonclients = {"sv_freezenonclients", "0", CVAR_NONE};
cvar_t sv_gameplayfix_spawnbeforethinks = {"sv_gameplayfix_spawnbeforethinks", "0", CVAR_NONE};
cvar_t sv_gameplayfix_bouncedownslopes = {"sv_gameplayfix_bouncedownslopes", "1", CVAR_NONE}; // fixes grenades making horrible noises on slopes.
cvar_t sv_fastpushmove = {"sv_fastpushmove", "0", CVAR_ARCHIVE}; // 0=old SV_PushMove processing; 1= faster SV_PushMove, with bugs ?

#define MOVE_EPSILON 0.01

Expand All @@ -57,6 +58,8 @@ static void SV_Physics_Toss (edict_t *ent);
// For usage by SV_PushMove, allocate at max possible size
static edict_t *moved_edict[MAX_EDICTS];
static vec3_t moved_from[MAX_EDICTS];
static edict_t *pushable_ent_cache[MAX_EDICTS];
static int num_pushable_ent_cache;

/*
================
Expand Down Expand Up @@ -453,7 +456,7 @@ cvar_t sv_gameplayfix_elevators = {"sv_gameplayfix_elevators", "2", CVAR_ARCHIVE

static void SV_PushMove (edict_t *pusher, float movetime)
{
int i, e;
int i;
edict_t *check, *block;
vec3_t mins, maxs, move;
vec3_t entorig, pushorig;
Expand Down Expand Up @@ -483,16 +486,39 @@ static void SV_PushMove (edict_t *pusher, float movetime)

// see if any solid entities are inside the final position
num_moved = 0;

const bool fast_pushers = (sv_fastpushmove.value > 0.f);

int e = -1;

// beware, we skip entity 0:
check = NEXT_EDICT (qcvm->edicts);
for (e = 1; e < qcvm->num_edicts; e++, check = NEXT_EDICT (check))

while (true)
{
qboolean riding = false;
// TBC :does qcvm->num_edicts always constant here, i.e is there edicts allocs possible in this loop ?
if (e >= (fast_pushers ? num_pushable_ent_cache - 1 : qcvm->num_edicts - 1 - 1))
break;

e++;

if (fast_pushers)
{
check = pushable_ent_cache[e];
}
else if (e > 0)
{
check = NEXT_EDICT (check);
}

if (check->free)
continue;

if (check->v.movetype == MOVETYPE_PUSH || check->v.movetype == MOVETYPE_NONE || check->v.movetype == MOVETYPE_NOCLIP)
continue;

qboolean riding = false;

// if the entity is standing on the pusher, it will definately be moved
if (!(((int)check->v.flags & FL_ONGROUND) && PROG_TO_EDICT (check->v.groundentity) == pusher))
{
Expand Down Expand Up @@ -554,6 +580,7 @@ static void SV_PushMove (edict_t *pusher, float movetime)
{ // fail the move
if (check->v.mins[0] == check->v.maxs[0])
continue;

if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER)
{ // corpse
check->v.mins[0] = check->v.mins[1] = 0;
Expand Down Expand Up @@ -1271,6 +1298,23 @@ void SV_Physics (void)
else
entity_cap = qcvm->num_edicts;

// fill the pushable entities cache
if (sv_fastpushmove.value > 0.f)
{
num_pushable_ent_cache = 0;
// beware, we skip entity 0 here:
edict_t *check = NEXT_EDICT (qcvm->edicts);
for (int e = 1; e < qcvm->num_edicts; e++, check = NEXT_EDICT (check))
{
if (check->free)
continue;
if (check->v.movetype == MOVETYPE_PUSH || check->v.movetype == MOVETYPE_NONE || check->v.movetype == MOVETYPE_NOCLIP)
continue;

pushable_ent_cache[num_pushable_ent_cache++] = check;
}
}

// for (i=0 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
for (i = 0; i < entity_cap; i++, ent = NEXT_EDICT (ent))
{
Expand Down
Loading