added sv_areadebug cvar which disables the use of the areagrid (VERY bad
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 12 Oct 2011 10:16:57 +0000 (10:16 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 12 Oct 2011 10:16:57 +0000 (10:16 +0000)
for performance, use ONLY for testing collision bugs)
added a small padding value (1 unit) to areagrid queries

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11402 d7cf8633-e32d-0410-b094-e92efae38249

server.h
sv_main.c
sv_phys.c
svvm_cmds.c
world.c

index d55f0f0..6eb6057 100644 (file)
--- a/server.h
+++ b/server.h
@@ -476,6 +476,7 @@ extern cvar_t sv_stopspeed;
 extern cvar_t sv_wallfriction;
 extern cvar_t sv_wateraccelerate;
 extern cvar_t sv_waterfriction;
+extern cvar_t sv_areadebug;
 extern cvar_t sys_ticrate;
 extern cvar_t teamplay;
 extern cvar_t temp1;
@@ -556,6 +557,7 @@ int SV_GenericHitSuperContentsMask(const prvm_edict_t *edict);
 trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask);
 trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask);
 trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask);
+int SV_EntitiesInBox(const vec3_t mins, const vec3_t maxs, int maxedicts, prvm_edict_t **resultedicts);
 
 qboolean SV_CanSeeBox(int numsamples, vec_t enlarge, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs);
 
index 9b41eca..0e19f3a 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -151,6 +151,7 @@ cvar_t sv_warsowbunny_topspeed = {0, "sv_warsowbunny_topspeed", "925", "soft spe
 cvar_t sv_warsowbunny_turnaccel = {0, "sv_warsowbunny_turnaccel", "0", "max sharpness of turns (also master switch for the sv_warsowbunny_* mode; set this to 9 to enable)"};
 cvar_t sv_warsowbunny_backtosideratio = {0, "sv_warsowbunny_backtosideratio", "0.8", "lower values make it easier to change direction without losing speed; the drawback is \"understeering\" in sharp turns"};
 cvar_t sv_onlycsqcnetworking = {0, "sv_onlycsqcnetworking", "0", "disables legacy entity networking code for higher performance (except on clients, which can still be legacy)"};
+cvar_t sv_areadebug = {0, "sv_areadebug", "0", "disables physics culling for debugging purposes (only for development)"};
 cvar_t sys_ticrate = {CVAR_SAVE, "sys_ticrate","0.0138889", "how long a server frame is in seconds, 0.05 is 20fps server rate, 0.1 is 10fps (can not be set higher than 0.1), 0 runs as many server frames as possible (makes games against bots a little smoother, overwhelms network players), 0.0138889 matches QuakeWorld physics"};
 cvar_t teamplay = {CVAR_NOTIFY, "teamplay","0", "teamplay mode, values depend on mod but typically 0 = no teams, 1 = no team damage no self damage, 2 = team damage and self damage, some mods support 3 = no team damage but can damage self"};
 cvar_t timelimit = {CVAR_NOTIFY, "timelimit","0", "ends level at this time (in minutes)"};
@@ -558,6 +559,7 @@ void SV_Init (void)
        Cvar_RegisterVariable (&sv_warsowbunny_turnaccel);
        Cvar_RegisterVariable (&sv_warsowbunny_backtosideratio);
        Cvar_RegisterVariable (&sv_onlycsqcnetworking);
+       Cvar_RegisterVariable (&sv_areadebug);
        Cvar_RegisterVariable (&sys_ticrate);
        Cvar_RegisterVariable (&teamplay);
        Cvar_RegisterVariable (&timelimit);
@@ -1513,7 +1515,7 @@ qboolean SV_CanSeeBox(int numtraces, vec_t enlarge, vec3_t eye, vec3_t entboxmin
 
        // get the list of entities in the sweep box
        if (sv_cullentities_trace_entityocclusion.integer)
-               numtouchedicts = World_EntitiesInBox(&sv.world, clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
+               numtouchedicts = SV_EntitiesInBox(clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
        if (numtouchedicts > MAX_EDICTS)
        {
                // this never happens
index c21044d..c0142c5 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -174,7 +174,7 @@ trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int
        // clip to entities
        // because this uses World_EntitiestoBox, we know all entity boxes overlap
        // the clip region, so we can skip culling checks in the loop below
-       numtouchedicts = World_EntitiesInBox(&sv.world, clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
+       numtouchedicts = SV_EntitiesInBox(clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
        if (numtouchedicts > MAX_EDICTS)
        {
                // this never happens
@@ -340,7 +340,7 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
        // clip to entities
        // because this uses World_EntitiestoBox, we know all entity boxes overlap
        // the clip region, so we can skip culling checks in the loop below
-       numtouchedicts = World_EntitiesInBox(&sv.world, clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
+       numtouchedicts = SV_EntitiesInBox(clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
        if (numtouchedicts > MAX_EDICTS)
        {
                // this never happens
@@ -553,7 +553,7 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
        // clip to entities
        // because this uses World_EntitiestoBox, we know all entity boxes overlap
        // the clip region, so we can skip culling checks in the loop below
-       numtouchedicts = World_EntitiesInBox(&sv.world, clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
+       numtouchedicts = SV_EntitiesInBox(clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
        if (numtouchedicts > MAX_EDICTS)
        {
                // this never happens
@@ -662,7 +662,7 @@ int SV_PointSuperContents(const vec3_t point)
                return supercontents;
 
        // get list of entities at this point
-       numtouchedicts = World_EntitiesInBox(&sv.world, point, point, MAX_EDICTS, touchedicts);
+       numtouchedicts = SV_EntitiesInBox(point, point, MAX_EDICTS, touchedicts);
        if (numtouchedicts > MAX_EDICTS)
        {
                // this never happens
@@ -699,6 +699,34 @@ Linking entities into the world culling system
 ===============================================================================
 */
 
+int SV_EntitiesInBox(const vec3_t mins, const vec3_t maxs, int maxedicts, prvm_edict_t **resultedicts)
+{
+       vec3_t paddedmins, paddedmaxs;
+       if (maxedicts < 1 || resultedicts == NULL)
+               return 0;
+       VectorSet(paddedmins, mins[0] - 10, mins[1] - 10, mins[2] - 1);
+       VectorSet(paddedmaxs, maxs[0] + 10, maxs[1] + 10, maxs[2] + 1);
+       if (sv_areadebug.integer)
+       {
+               int numresultedicts = 0;
+               int edictindex;
+               prvm_edict_t *ed;
+               for (edictindex = 1;edictindex < prog->num_edicts;edictindex++)
+               {
+                       ed = PRVM_EDICT_NUM(edictindex);
+                       if (!ed->priv.required->free && BoxesOverlap(PRVM_serveredictvector(ed, absmin), PRVM_serveredictvector(ed, absmax), paddedmins, paddedmaxs))
+                       {
+                               resultedicts[numresultedicts++] = ed;
+                               if (numresultedicts == maxedicts)
+                                       break;
+                       }
+               }
+               return numresultedicts;
+       }
+       else
+               return World_EntitiesInBox(&sv.world, paddedmins, paddedmaxs, maxedicts, resultedicts);
+}
+
 void SV_LinkEdict_TouchAreaGrid_Call(prvm_edict_t *touch, prvm_edict_t *ent)
 {
        PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(touch);
@@ -737,7 +765,7 @@ void SV_LinkEdict_TouchAreaGrid(prvm_edict_t *ent)
 
        // build a list of edicts to touch, because the link loop can be corrupted
        // by IncreaseEdicts called during touch functions
-       numtouchedicts = World_EntitiesInBox(&sv.world, ent->priv.server->areamins, ent->priv.server->areamaxs, MAX_EDICTS, touchedicts);
+       numtouchedicts = SV_EntitiesInBox(ent->priv.server->areamins, ent->priv.server->areamaxs, MAX_EDICTS, touchedicts);
        if (numtouchedicts > MAX_EDICTS)
        {
                // this never happens
@@ -1777,7 +1805,7 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime)
        if (PRVM_serveredictfloat(pusher, movetype) == MOVETYPE_FAKEPUSH) // Tenebrae's MOVETYPE_PUSH variant that doesn't push...
                numcheckentities = 0;
        else // MOVETYPE_PUSH
-               numcheckentities = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, checkentities);
+               numcheckentities = SV_EntitiesInBox(mins, maxs, MAX_EDICTS, checkentities);
        for (e = 0;e < numcheckentities;e++)
        {
                prvm_edict_t *check = checkentities[e];
index c0ed230..246ff1d 100644 (file)
@@ -994,7 +994,7 @@ static void VM_SV_findradius (void)
        maxs[0] = org[0] + (radius + 1);
        maxs[1] = org[1] + (radius + 1);
        maxs[2] = org[2] + (radius + 1);
-       numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
+       numtouchedicts = SV_EntitiesInBox(mins, maxs, MAX_EDICTS, touchedicts);
        if (numtouchedicts > MAX_EDICTS)
        {
                // this never happens
diff --git a/world.c b/world.c
index f228ec5..ec767e0 100644 (file)
--- a/world.c
+++ b/world.c
@@ -173,24 +173,28 @@ void World_UnlinkEdict(prvm_edict_t *ent)
        }
 }
 
-int World_EntitiesInBox(world_t *world, const vec3_t mins, const vec3_t maxs, int maxlist, prvm_edict_t **list)
+int World_EntitiesInBox(world_t *world, const vec3_t requestmins, const vec3_t requestmaxs, int maxlist, prvm_edict_t **list)
 {
        int numlist;
        link_t *grid;
        link_t *l;
        prvm_edict_t *ent;
+       vec3_t paddedmins, paddedmaxs;
        int igrid[3], igridmins[3], igridmaxs[3];
 
+       VectorSet(paddedmins, requestmins[0] - 1.0f, requestmins[1] - 1.0f, requestmins[2] - 1.0f);
+       VectorSet(paddedmaxs, requestmaxs[0] + 1.0f, requestmaxs[1] + 1.0f, requestmaxs[2] + 1.0f);
+
        // FIXME: if areagrid_marknumber wraps, all entities need their
        // ent->priv.server->areagridmarknumber reset
        world->areagrid_stats_calls++;
        world->areagrid_marknumber++;
-       igridmins[0] = (int) floor((mins[0] + world->areagrid_bias[0]) * world->areagrid_scale[0]);
-       igridmins[1] = (int) floor((mins[1] + world->areagrid_bias[1]) * world->areagrid_scale[1]);
-       //igridmins[2] = (int) ((mins[2] + world->areagrid_bias[2]) * world->areagrid_scale[2]);
-       igridmaxs[0] = (int) floor((maxs[0] + world->areagrid_bias[0]) * world->areagrid_scale[0]) + 1;
-       igridmaxs[1] = (int) floor((maxs[1] + world->areagrid_bias[1]) * world->areagrid_scale[1]) + 1;
-       //igridmaxs[2] = (int) ((maxs[2] + world->areagrid_bias[2]) * world->areagrid_scale[2]) + 1;
+       igridmins[0] = (int) floor((paddedmins[0] + world->areagrid_bias[0]) * world->areagrid_scale[0]);
+       igridmins[1] = (int) floor((paddedmins[1] + world->areagrid_bias[1]) * world->areagrid_scale[1]);
+       //igridmins[2] = (int) ((paddedmins[2] + world->areagrid_bias[2]) * world->areagrid_scale[2]);
+       igridmaxs[0] = (int) floor((paddedmaxs[0] + world->areagrid_bias[0]) * world->areagrid_scale[0]) + 1;
+       igridmaxs[1] = (int) floor((paddedmaxs[1] + world->areagrid_bias[1]) * world->areagrid_scale[1]) + 1;
+       //igridmaxs[2] = (int) ((paddedmaxs[2] + world->areagrid_bias[2]) * world->areagrid_scale[2]) + 1;
        igridmins[0] = max(0, igridmins[0]);
        igridmins[1] = max(0, igridmins[1]);
        //igridmins[2] = max(0, igridmins[2]);
@@ -198,6 +202,9 @@ int World_EntitiesInBox(world_t *world, const vec3_t mins, const vec3_t maxs, in
        igridmaxs[1] = min(AREA_GRID, igridmaxs[1]);
        //igridmaxs[2] = min(AREA_GRID, igridmaxs[2]);
 
+       // paranoid debugging
+       //VectorSet(igridmins, 0, 0, 0);VectorSet(igridmaxs, AREA_GRID, AREA_GRID, AREA_GRID);
+
        numlist = 0;
        // add entities not linked into areagrid because they are too big or
        // outside the grid bounds
@@ -210,7 +217,7 @@ int World_EntitiesInBox(world_t *world, const vec3_t mins, const vec3_t maxs, in
                        if (ent->priv.server->areagridmarknumber != world->areagrid_marknumber)
                        {
                                ent->priv.server->areagridmarknumber = world->areagrid_marknumber;
-                               if (!ent->priv.server->free && BoxesOverlap(mins, maxs, ent->priv.server->areamins, ent->priv.server->areamaxs))
+                               if (!ent->priv.server->free && BoxesOverlap(paddedmins, paddedmaxs, ent->priv.server->areamins, ent->priv.server->areamaxs))
                                {
                                        if (numlist < maxlist)
                                                list[numlist] = ent;
@@ -234,7 +241,7 @@ int World_EntitiesInBox(world_t *world, const vec3_t mins, const vec3_t maxs, in
                                        if (ent->priv.server->areagridmarknumber != world->areagrid_marknumber)
                                        {
                                                ent->priv.server->areagridmarknumber = world->areagrid_marknumber;
-                                               if (!ent->priv.server->free && BoxesOverlap(mins, maxs, ent->priv.server->areamins, ent->priv.server->areamaxs))
+                                               if (!ent->priv.server->free && BoxesOverlap(paddedmins, paddedmaxs, ent->priv.server->areamins, ent->priv.server->areamaxs))
                                                {
                                                        if (numlist < maxlist)
                                                                list[numlist] = ent;