From 06724db2d67c1f2be1cebc3e108baae1053dd436 Mon Sep 17 00:00:00 2001 From: div0 Date: Wed, 18 Mar 2009 11:22:22 +0000 Subject: [PATCH] use checkpvs() for bot waypointing redstarrepublic now relinks twice as fast git-svn-id: svn://svn.icculus.org/nexuiz/trunk@6211 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- data/qcsrc/server/bots.qc | 66 +++++++++++++++++++-------------- data/qcsrc/server/extensions.qh | 20 ++++++++++ 2 files changed, 59 insertions(+), 27 deletions(-) diff --git a/data/qcsrc/server/bots.qc b/data/qcsrc/server/bots.qc index 969d587b1..f27d4ada0 100644 --- a/data/qcsrc/server/bots.qc +++ b/data/qcsrc/server/bots.qc @@ -486,6 +486,9 @@ void waypoint_addlink(entity from, entity to) from.wp00 = to;from.wp00mincost = c;return; }; +// fields you can query using prvm_global server to get some statistics about waypoint linking culling +float relink_total, relink_walkculled, relink_pvsculled, relink_lengthculled; + // relink this spawnfunc_waypoint // (precompile a list of all reachable waypoints from this spawnfunc_waypoint) // (SLOW!) @@ -496,9 +499,8 @@ void waypoint_think() //dprint("waypoint_think wpisbox = ", ftos(self.wpisbox), "\n"); sm1 = self.origin + self.mins; sm2 = self.origin + self.maxs; - e = find(world, classname, "waypoint"); stepheightvec = cvar("sv_stepheight") * '0 0 1'; - while (e) + for(e = world; (e = find(e, classname, "waypoint")); ) { if (boxesoverlap(self.absmin, self.absmax, e.absmin, e.absmax)) { @@ -507,6 +509,12 @@ void waypoint_think() } else { + ++relink_total; + if(!checkpvs(self.origin, e)) + { + ++relink_pvsculled; + continue; + } sv = e.origin; sv_x = bound(sm1_x, sv_x, sm2_x); sv_y = bound(sm1_y, sv_y, sm2_y); @@ -519,38 +527,41 @@ void waypoint_think() ev_z = bound(em1_z, ev_z, em2_z); dv = ev - sv; dv_z = 0; - if (vlen(dv) < 1050) // max search distance in XY + if (vlen(dv) >= 1050) // max search distance in XY { - navigation_testtracewalk = 0; - if (!self.wpisbox) + ++relink_lengthculled; + continue; + } + navigation_testtracewalk = 0; + if (!self.wpisbox) + { + tracebox(sv - PL_MIN_z * '0 0 1', PL_MIN, PL_MAX, sv, FALSE, self); + if (!trace_startsolid) { - tracebox(sv - PL_MIN_z * '0 0 1', PL_MIN, PL_MAX, sv, FALSE, self); - if (!trace_startsolid) - { - //dprint("sv deviation", vtos(trace_endpos - sv), "\n"); - sv = trace_endpos + '0 0 1'; - } + //dprint("sv deviation", vtos(trace_endpos - sv), "\n"); + sv = trace_endpos + '0 0 1'; } - if (!e.wpisbox) + } + if (!e.wpisbox) + { + tracebox(ev - PL_MIN_z * '0 0 1', PL_MIN, PL_MAX, ev, FALSE, e); + if (!trace_startsolid) { - tracebox(ev - PL_MIN_z * '0 0 1', PL_MIN, PL_MAX, ev, FALSE, e); - if (!trace_startsolid) - { - //dprint("ev deviation", vtos(trace_endpos - ev), "\n"); - ev = trace_endpos + '0 0 1'; - } + //dprint("ev deviation", vtos(trace_endpos - ev), "\n"); + ev = trace_endpos + '0 0 1'; } - //traceline(self.origin, e.origin, FALSE, world); - //if (trace_fraction == 1) - if (!self.wpisbox) - if (tracewalk(self, sv, PL_MIN, PL_MAX, ev, MOVE_NOMONSTERS)) - waypoint_addlink(self, e); - if (!e.wpisbox) - if (tracewalk(e, ev, PL_MIN, PL_MAX, sv, MOVE_NOMONSTERS)) - waypoint_addlink(e, self); } + //traceline(self.origin, e.origin, FALSE, world); + //if (trace_fraction == 1) + if (!self.wpisbox && tracewalk(self, sv, PL_MIN, PL_MAX, ev, MOVE_NOMONSTERS)) + waypoint_addlink(self, e); + else + relink_walkculled += 0.5; + if (!e.wpisbox && tracewalk(e, ev, PL_MIN, PL_MAX, sv, MOVE_NOMONSTERS)) + waypoint_addlink(e, self); + else + relink_walkculled += 0.5; } - e = find(e, classname, "waypoint"); } navigation_testtracewalk = 0; }; @@ -759,6 +770,7 @@ void waypoint_removeall() void waypoint_schedulerelinkall() { local entity head; + relink_total = relink_walkculled = relink_pvsculled = relink_lengthculled = 0; head = findchain(classname, "waypoint"); while (head) { diff --git a/data/qcsrc/server/extensions.qh b/data/qcsrc/server/extensions.qh index 64f3868b7..de5f6265f 100644 --- a/data/qcsrc/server/extensions.qh +++ b/data/qcsrc/server/extensions.qh @@ -639,6 +639,18 @@ entity(.string fld, string match) findchain = #402; //description: //similar to find() but returns a chain of entities like findradius. +//DP_QC_FINDCHAIN_TOFIELD +//idea: div0 +//darkplaces implementation: div0 +//builtin definitions: +entity(.string fld, float match, .entity tofield) findradius_tofield = #22; +entity(.string fld, string match, .entity tofield) findchain_tofield = #402; +entity(.string fld, float match, .entity tofield) findchainflags_tofield = #450; +entity(.string fld, float match, .entity tofield) findchainfloat_tofield = #403; +//description: +//similar to findchain() etc, but stores the chain into .tofield instead of .chain +//actually, the .entity tofield is an optional field of the the existing findchain* functions + //DP_QC_FINDCHAINFLAGS //idea: Sajt //darkplaces implementation: LordHavoc @@ -1783,6 +1795,14 @@ float PFLAGS_FULLDYNAMIC = 128; // light enable (without this set no light is pr //description: //sv_jumpstep allows stepping up onto stairs while airborn, sv_stepheight controls how high a single step can be. +//FTE_QC_CHECKPVS +//idea: Urre +//darkplaces implementation: div0 +//builtin definitions: +float checkpvs(vector viewpos, entity viewee) = #240; +//description: +//returns true if viewee can be seen from viewpos according to PVS data + //FTE_STRINGS //idea: many //darkplaces implementation: KrimZon -- 2.39.2