From a6984b2a055eb337d57a8c4198fa9a9bb238cd8c Mon Sep 17 00:00:00 2001 From: havoc Date: Sat, 14 Apr 2018 05:20:44 +0000 Subject: [PATCH] Added r_cullentities_trace_expand and pad cvars, these configure additional ways to expand entity boxes when culling by traceline. Added r_vis_trace feature which allows you to turn on traceline-based culling of portals, and r_vis_trace_surfaces lets you cull surfaces by traceline (slow and probably pointless, but a curious feature). Added r_shadow_culllights_trace_expand and pad cvars. Added sv_cullentities_trace_expand to make SV_CanSeeBox be at feature parity with R_CanSeeBox. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12395 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rmain.c | 36 ++++++++++++++++++++++++------------ gl_rsurf.c | 37 +++++++++++++++++++++++++++++++++---- model_brush.h | 1 + r_shadow.c | 10 +++++++--- render.h | 2 +- server.h | 2 +- sv_main.c | 22 ++++++++++++---------- 7 files changed, 79 insertions(+), 31 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index 4842ee0b..386d12f3 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -114,6 +114,8 @@ cvar_t r_cullentities_trace_entityocclusion = { 0, "r_cullentities_trace_entityo cvar_t r_cullentities_trace_samples = {0, "r_cullentities_trace_samples", "2", "number of samples to test for entity culling (in addition to center sample)"}; cvar_t r_cullentities_trace_tempentitysamples = {0, "r_cullentities_trace_tempentitysamples", "-1", "number of samples to test for entity culling of temp entities (including all CSQC entities), -1 disables trace culling on these entities to prevent flicker (pvs still applies)"}; cvar_t r_cullentities_trace_enlarge = {0, "r_cullentities_trace_enlarge", "0", "box enlargement for entity culling"}; +cvar_t r_cullentities_trace_expand = {0, "r_cullentities_trace_expand", "0", "box expanded by this many units for entity culling"}; +cvar_t r_cullentities_trace_pad = {0, "r_cullentities_trace_pad", "8", "accept traces that hit within this many units of the box"}; cvar_t r_cullentities_trace_delay = {0, "r_cullentities_trace_delay", "1", "number of seconds until the entity gets actually culled"}; cvar_t r_cullentities_trace_eyejitter = {0, "r_cullentities_trace_eyejitter", "16", "randomly offset rays from the eye by this much to reduce the odds of flickering"}; cvar_t r_sortentities = {0, "r_sortentities", "0", "sort entities before drawing (might be faster)"}; @@ -4266,6 +4268,8 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_cullentities_trace_samples); Cvar_RegisterVariable(&r_cullentities_trace_tempentitysamples); Cvar_RegisterVariable(&r_cullentities_trace_enlarge); + Cvar_RegisterVariable(&r_cullentities_trace_expand); + Cvar_RegisterVariable(&r_cullentities_trace_pad); Cvar_RegisterVariable(&r_cullentities_trace_delay); Cvar_RegisterVariable(&r_cullentities_trace_eyejitter); Cvar_RegisterVariable(&r_sortentities); @@ -5023,11 +5027,12 @@ void R_AnimCache_CacheVisibleEntities(void) //================================================================================== -qboolean R_CanSeeBox(int numsamples, vec_t eyejitter, vec_t entboxenlarge, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs) +qboolean R_CanSeeBox(int numsamples, vec_t eyejitter, vec_t entboxenlarge, vec_t entboxexpand, vec_t pad, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs) { int i; vec3_t eyemins, eyemaxs; vec3_t boxmins, boxmaxs; + vec3_t padmins, padmaxs; vec3_t start; vec3_t end; dp_model_t *model = r_refdef.scene.worldmodel; @@ -5062,12 +5067,19 @@ qboolean R_CanSeeBox(int numsamples, vec_t eyejitter, vec_t entboxenlarge, vec3_ eyemins[2] = eye[2] - eyejitter; eyemaxs[2] = eye[2] + eyejitter; // expand the box a little - boxmins[0] = (entboxenlarge + 1) * entboxmins[0] - entboxenlarge * entboxmaxs[0]; - boxmaxs[0] = (entboxenlarge + 1) * entboxmaxs[0] - entboxenlarge * entboxmins[0]; - boxmins[1] = (entboxenlarge + 1) * entboxmins[1] - entboxenlarge * entboxmaxs[1]; - boxmaxs[1] = (entboxenlarge + 1) * entboxmaxs[1] - entboxenlarge * entboxmins[1]; - boxmins[2] = (entboxenlarge + 1) * entboxmins[2] - entboxenlarge * entboxmaxs[2]; - boxmaxs[2] = (entboxenlarge + 1) * entboxmaxs[2] - entboxenlarge * entboxmins[2]; + boxmins[0] = (entboxenlarge + 1) * entboxmins[0] - entboxenlarge * entboxmaxs[0] - entboxexpand; + boxmaxs[0] = (entboxenlarge + 1) * entboxmaxs[0] - entboxenlarge * entboxmins[0] + entboxexpand; + boxmins[1] = (entboxenlarge + 1) * entboxmins[1] - entboxenlarge * entboxmaxs[1] - entboxexpand; + boxmaxs[1] = (entboxenlarge + 1) * entboxmaxs[1] - entboxenlarge * entboxmins[1] + entboxexpand; + boxmins[2] = (entboxenlarge + 1) * entboxmins[2] - entboxenlarge * entboxmaxs[2] - entboxexpand; + boxmaxs[2] = (entboxenlarge + 1) * entboxmaxs[2] - entboxenlarge * entboxmins[2] + entboxexpand; + // make an even larger box for the acceptable area + padmins[0] = boxmins[0] - pad; + padmaxs[0] = boxmaxs[0] + pad; + padmins[1] = boxmins[1] - pad; + padmaxs[1] = boxmaxs[1] + pad; + padmins[2] = boxmins[2] - pad; + padmaxs[2] = boxmaxs[2] + pad; // return true if eye overlaps enlarged box if (BoxesOverlap(boxmins, boxmaxs, eyemins, eyemaxs)) @@ -5085,11 +5097,11 @@ qboolean R_CanSeeBox(int numsamples, vec_t eyejitter, vec_t entboxenlarge, vec3_ //trace_t trace = CL_TraceLine(start, end, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, SUPERCONTENTS_SKY, 0.0f, true, false, NULL, true, true); trace_t trace = CL_Cache_TraceLineSurfaces(start, end, MOVE_NORMAL, SUPERCONTENTS_SOLID, 0, MATERIALFLAGMASK_TRANSLUCENT); // not picky - if the trace ended anywhere in the box we're good - if (BoxesOverlap(trace.endpos, trace.endpos, boxmins, boxmaxs)) + if (BoxesOverlap(trace.endpos, trace.endpos, padmins, padmaxs)) return true; } } - else if (model->brush.TraceLineOfSight(model, start, end, boxmins, boxmaxs)) + else if (model->brush.TraceLineOfSight(model, start, end, padmins, padmaxs)) return true; // try various random positions @@ -5101,10 +5113,10 @@ qboolean R_CanSeeBox(int numsamples, vec_t eyejitter, vec_t entboxenlarge, vec3_ { trace_t trace = CL_Cache_TraceLineSurfaces(start, end, MOVE_NORMAL, SUPERCONTENTS_SOLID, 0, MATERIALFLAGMASK_TRANSLUCENT); // not picky - if the trace ended anywhere in the box we're good - if (BoxesOverlap(trace.endpos, trace.endpos, boxmins, boxmaxs)) + if (BoxesOverlap(trace.endpos, trace.endpos, padmins, padmaxs)) return true; } - else if (model->brush.TraceLineOfSight(model, start, end, boxmins, boxmaxs)) + else if (model->brush.TraceLineOfSight(model, start, end, padmins, padmaxs)) return true; } @@ -5163,7 +5175,7 @@ static void R_View_UpdateEntityVisible (void) if (!(ent->flags & (RENDER_VIEWMODEL | RENDER_WORLDOBJECT | RENDER_NODEPTHTEST)) && !(ent->model && (ent->model->name[0] == '*'))) { samples = ent->last_trace_visibility == 0 ? r_cullentities_trace_tempentitysamples.integer : r_cullentities_trace_samples.integer; - if (R_CanSeeBox(samples, r_cullentities_trace_eyejitter.value, r_cullentities_trace_enlarge.value, r_refdef.view.origin, ent->mins, ent->maxs)) + if (R_CanSeeBox(samples, r_cullentities_trace_eyejitter.value, r_cullentities_trace_enlarge.value, r_cullentities_trace_expand.value, r_cullentities_trace_pad.value, r_refdef.view.origin, ent->mins, ent->maxs)) ent->last_trace_visibility = realtime; if (ent->last_trace_visibility < realtime - r_cullentities_trace_delay.value) r_refdef.viewcache.entityvisible[i] = 0; diff --git a/gl_rsurf.c b/gl_rsurf.c index 130e7453..d0477c3d 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -30,6 +30,14 @@ cvar_t r_lockpvs = {0, "r_lockpvs", "0", "disables pvs switching, allows you to cvar_t r_lockvisibility = {0, "r_lockvisibility", "0", "disables visibility updates, allows you to walk around and inspect what is visible from a given viewpoint in the map (anything offscreen at the moment this is enabled will not be drawn)"}; cvar_t r_useportalculling = {0, "r_useportalculling", "2", "improve framerate with r_novis 1 by using portal culling - still not as good as compiled visibility data in the map, but it helps (a value of 2 forces use of this even with vis data, which improves framerates in maps without too much complexity, but hurts in extremely complex maps, which is why 2 is not the default mode)"}; cvar_t r_usesurfaceculling = {0, "r_usesurfaceculling", "1", "skip off-screen surfaces (1 = cull surfaces if the map is likely to benefit, 2 = always cull surfaces)"}; +cvar_t r_vis_trace = {0, "r_vis_trace", "0", "test if each portal or leaf is visible using tracelines"}; +cvar_t r_vis_trace_samples = {0, "r_vis_trace_samples", "1", "use this many randomly positioned tracelines each frame to refresh the visible timer"}; +cvar_t r_vis_trace_delay = {0, "r_vis_trace_delay", "1", "keep a portal visible for this many seconds"}; +cvar_t r_vis_trace_eyejitter = {0, "r_vis_trace_eyejitter", "8", "use a random offset of this much on the start of each traceline"}; +cvar_t r_vis_trace_enlarge = {0, "r_vis_trace_enlarge", "0", "make portal bounds bigger for tests by (1+this)*size"}; +cvar_t r_vis_trace_expand = {0, "r_vis_trace_expand", "0", "make portal bounds bigger for tests by this many units"}; +cvar_t r_vis_trace_pad = {0, "r_vis_trace_pad", "8", "accept traces that hit within this many units of the portal"}; +cvar_t r_vis_trace_surfaces = {0, "r_vis_trace_surfaces", "0", "also use tracelines to cull surfaces"}; cvar_t r_q3bsp_renderskydepth = {0, "r_q3bsp_renderskydepth", "0", "draws sky depth masking in q3 maps (as in q1 maps), this means for example that sky polygons can hide other things"}; /* @@ -418,9 +426,15 @@ static void R_View_WorldVisibility_CullSurfaces(void) surfaceindexend = surfaceindexstart + model->nummodelsurfaces; surfaces = model->data_surfaces; surfacevisible = r_refdef.viewcache.world_surfacevisible; - for (surfaceindex = surfaceindexstart;surfaceindex < surfaceindexend;surfaceindex++) - if (surfacevisible[surfaceindex] && R_CullBox(surfaces[surfaceindex].mins, surfaces[surfaceindex].maxs)) - surfacevisible[surfaceindex] = 0; + for (surfaceindex = surfaceindexstart; surfaceindex < surfaceindexend; surfaceindex++) + { + if (surfacevisible[surfaceindex]) + { + if (R_CullBox(surfaces[surfaceindex].mins, surfaces[surfaceindex].maxs) + || (r_vis_trace_surfaces.integer && !R_CanSeeBox(r_vis_trace_samples.integer, r_vis_trace_eyejitter.value, r_vis_trace_enlarge.value, r_vis_trace_expand.value, r_vis_trace_pad.value, r_refdef.view.origin, surfaces[surfaceindex].mins, surfaces[surfaceindex].maxs))) + surfacevisible[surfaceindex] = 0; + } + } } void R_View_WorldVisibility(qboolean forcenovis) @@ -568,6 +582,13 @@ void R_View_WorldVisibility(qboolean forcenovis) cullmaxs[2] = p->maxs[2] + cullbias; if (R_CullBox(cullmins, cullmaxs)) continue; + if (r_vis_trace.integer) + { + if (p->tracetime != realtime && R_CanSeeBox(r_vis_trace_samples.value, r_vis_trace_eyejitter.value, r_vis_trace_enlarge.value, r_vis_trace_expand.value, r_vis_trace_pad.value, r_refdef.view.origin, cullmins, cullmaxs)) + p->tracetime = realtime; + if (realtime - p->tracetime > r_vis_trace_delay.value) + continue; + } if (leafstackpos >= (int)(sizeof(leafstack) / sizeof(leafstack[0]))) break; leafstack[leafstackpos++] = p->past; @@ -576,7 +597,7 @@ void R_View_WorldVisibility(qboolean forcenovis) } } - R_View_WorldVisibility_CullSurfaces(); + R_View_WorldVisibility_CullSurfaces(); } void R_Q1BSP_DrawSky(entity_render_t *ent) @@ -1633,6 +1654,14 @@ void GL_Surf_Init(void) Cvar_RegisterVariable(&r_lockvisibility); Cvar_RegisterVariable(&r_useportalculling); Cvar_RegisterVariable(&r_usesurfaceculling); + Cvar_RegisterVariable(&r_vis_trace); + Cvar_RegisterVariable(&r_vis_trace_samples); + Cvar_RegisterVariable(&r_vis_trace_delay); + Cvar_RegisterVariable(&r_vis_trace_eyejitter); + Cvar_RegisterVariable(&r_vis_trace_enlarge); + Cvar_RegisterVariable(&r_vis_trace_expand); + Cvar_RegisterVariable(&r_vis_trace_pad); + Cvar_RegisterVariable(&r_vis_trace_surfaces); Cvar_RegisterVariable(&r_q3bsp_renderskydepth); Cmd_AddCommand ("r_replacemaptexture", R_ReplaceWorldTexture, "override a map texture for testing purposes"); diff --git a/model_brush.h b/model_brush.h index 3b1d6162..9eae6abb 100644 --- a/model_brush.h +++ b/model_brush.h @@ -219,6 +219,7 @@ typedef struct mportal_s mvertex_t *points; vec3_t mins, maxs; // culling mplane_t plane; + double tracetime; // refreshed to realtime by traceline tests } mportal_t; diff --git a/r_shadow.c b/r_shadow.c index c7ecb5a1..b880ab00 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -340,7 +340,9 @@ cvar_t r_shadow_texture3d = {0, "r_shadow_texture3d", "1", "use 3D voxel texture cvar_t r_shadow_culllights_pvs = {CVAR_SAVE, "r_shadow_culllights_pvs", "1", "check if light overlaps any visible bsp leafs when determining if the light is visible"}; cvar_t r_shadow_culllights_trace = {CVAR_SAVE, "r_shadow_culllights_trace", "1", "use raytraces from the eye to random places within light bounds to determine if the light is visible"}; cvar_t r_shadow_culllights_trace_eyejitter = {CVAR_SAVE, "r_shadow_culllights_trace_eyejitter", "16", "offset eye location randomly by this much"}; -cvar_t r_shadow_culllights_trace_enlarge = {CVAR_SAVE, "r_shadow_culllights_trace_enlarge", "0.1", "make light bounds bigger by *1.0+enlarge"}; +cvar_t r_shadow_culllights_trace_enlarge = {CVAR_SAVE, "r_shadow_culllights_trace_enlarge", "0", "make light bounds bigger by *(1.0+enlarge)"}; +cvar_t r_shadow_culllights_trace_expand = {CVAR_SAVE, "r_shadow_culllights_trace_expand", "8", "make light bounds bigger by this many units"}; +cvar_t r_shadow_culllights_trace_pad = {CVAR_SAVE, "r_shadow_culllights_trace_expand", "8", "accept traces that hit within this many units of the light bounds"}; cvar_t r_shadow_culllights_trace_samples = {CVAR_SAVE, "r_shadow_culllights_trace_samples", "16", "use this many traces to random positions (in addition to center trace)"}; cvar_t r_shadow_culllights_trace_tempsamples = {CVAR_SAVE, "r_shadow_culllights_trace_tempsamples", "16", "use this many traces if the light was created by csqc (no inter-frame caching), -1 disables the check (to avoid flicker entirely)"}; cvar_t r_shadow_culllights_trace_delay = {CVAR_SAVE, "r_shadow_culllights_trace_delay", "1", "light will be considered visible for this many seconds after any trace connects"}; @@ -818,6 +820,8 @@ void R_Shadow_Init(void) Cvar_RegisterVariable(&r_shadow_culllights_trace); Cvar_RegisterVariable(&r_shadow_culllights_trace_eyejitter); Cvar_RegisterVariable(&r_shadow_culllights_trace_enlarge); + Cvar_RegisterVariable(&r_shadow_culllights_trace_expand); + Cvar_RegisterVariable(&r_shadow_culllights_trace_pad); Cvar_RegisterVariable(&r_shadow_culllights_trace_samples); Cvar_RegisterVariable(&r_shadow_culllights_trace_tempsamples); Cvar_RegisterVariable(&r_shadow_culllights_trace_delay); @@ -2874,7 +2878,7 @@ static void R_Shadow_BounceGrid_AssignPhotons(r_shadow_bouncegrid_settings_t *se // is probably fine (and they use the same timer) if (r_shadow_culllights_trace.integer) { - if (rtlight->trace_timer != realtime && R_CanSeeBox(rtlight->trace_timer == 0 ? r_shadow_culllights_trace_tempsamples.integer : r_shadow_culllights_trace_samples.integer, r_shadow_culllights_trace_eyejitter.value, r_shadow_culllights_trace_enlarge.value, r_refdef.view.origin, rtlight->cullmins, rtlight->cullmaxs)) + if (rtlight->trace_timer != realtime && R_CanSeeBox(rtlight->trace_timer == 0 ? r_shadow_culllights_trace_tempsamples.integer : r_shadow_culllights_trace_samples.integer, r_shadow_culllights_trace_eyejitter.value, r_shadow_culllights_trace_enlarge.value, r_shadow_culllights_trace_expand.value, r_shadow_culllights_trace_pad.value, r_refdef.view.origin, rtlight->cullmins, rtlight->cullmaxs)) rtlight->trace_timer = realtime; if (realtime - rtlight->trace_timer > r_shadow_culllights_trace_delay.value) return; @@ -4707,7 +4711,7 @@ static void R_Shadow_PrepareLight(rtlight_t *rtlight) // skip if the light box is not visible to traceline if (r_shadow_culllights_trace.integer) { - if (rtlight->trace_timer != realtime && R_CanSeeBox(rtlight->trace_timer == 0 ? r_shadow_culllights_trace_tempsamples.integer : r_shadow_culllights_trace_samples.integer, r_shadow_culllights_trace_eyejitter.value, r_shadow_culllights_trace_enlarge.value, r_refdef.view.origin, rtlight->cullmins, rtlight->cullmaxs)) + if (rtlight->trace_timer != realtime && R_CanSeeBox(rtlight->trace_timer == 0 ? r_shadow_culllights_trace_tempsamples.integer : r_shadow_culllights_trace_samples.integer, r_shadow_culllights_trace_eyejitter.value, r_shadow_culllights_trace_enlarge.value, r_shadow_culllights_trace_expand.value, r_shadow_culllights_trace_pad.value, r_refdef.view.origin, rtlight->cullmins, rtlight->cullmaxs)) rtlight->trace_timer = realtime; if (realtime - rtlight->trace_timer > r_shadow_culllights_trace_delay.value) return; diff --git a/render.h b/render.h index 5ae6304a..df88749a 100644 --- a/render.h +++ b/render.h @@ -166,7 +166,7 @@ void R_DrawExplosions(void); int R_CullBox(const vec3_t mins, const vec3_t maxs); int R_CullBoxCustomPlanes(const vec3_t mins, const vec3_t maxs, int numplanes, const mplane_t *planes); -qboolean R_CanSeeBox(int numsamples, vec_t eyejitter, vec_t entboxenlarge, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs); +qboolean R_CanSeeBox(int numsamples, vec_t eyejitter, vec_t entboxenlarge, vec_t entboxexpand, vec_t pad, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs); #include "r_modules.h" diff --git a/server.h b/server.h index bfd20ecb..bd35e7bd 100644 --- a/server.h +++ b/server.h @@ -582,7 +582,7 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_ trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask); int SV_EntitiesInBox(const vec3_t mins, const vec3_t maxs, int maxedicts, prvm_edict_t **resultedicts); -qboolean SV_CanSeeBox(int numsamples, vec_t eyejitter, vec_t enlarge, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs); +qboolean SV_CanSeeBox(int numsamples, vec_t eyejitter, vec_t enlarge, vec_t entboxexpand, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs); int SV_PointSuperContents(const vec3_t point); diff --git a/sv_main.c b/sv_main.c index d724aa1f..f315a3a7 100644 --- a/sv_main.c +++ b/sv_main.c @@ -81,6 +81,7 @@ cvar_t sv_cullentities_trace = {0, "sv_cullentities_trace", "0", "somewhat slow cvar_t sv_cullentities_trace_delay = {0, "sv_cullentities_trace_delay", "1", "number of seconds until the entity gets actually culled"}; cvar_t sv_cullentities_trace_delay_players = {0, "sv_cullentities_trace_delay_players", "0.2", "number of seconds until the entity gets actually culled if it is a player entity"}; cvar_t sv_cullentities_trace_enlarge = {0, "sv_cullentities_trace_enlarge", "0", "box enlargement for entity culling"}; +cvar_t sv_cullentities_trace_expand = { 0, "sv_cullentities_trace_expand", "0", "box is expanded by this many units for entity culling" }; cvar_t sv_cullentities_trace_eyejitter = {0, "sv_cullentities_trace_eyejitter", "16", "jitter the eye by this much for each trace"}; cvar_t sv_cullentities_trace_prediction = {0, "sv_cullentities_trace_prediction", "1", "also trace from the predicted player position"}; cvar_t sv_cullentities_trace_prediction_time = {0, "sv_cullentities_trace_prediction_time", "0.2", "how many seconds of prediction to use"}; @@ -494,6 +495,7 @@ void SV_Init (void) Cvar_RegisterVariable (&sv_cullentities_trace_delay); Cvar_RegisterVariable (&sv_cullentities_trace_delay_players); Cvar_RegisterVariable (&sv_cullentities_trace_enlarge); + Cvar_RegisterVariable (&sv_cullentities_trace_expand); Cvar_RegisterVariable (&sv_cullentities_trace_eyejitter); Cvar_RegisterVariable (&sv_cullentities_trace_entityocclusion); Cvar_RegisterVariable (&sv_cullentities_trace_prediction); @@ -1487,7 +1489,7 @@ static void SV_PrepareEntitiesForSending(void) #define MAX_LINEOFSIGHTTRACES 64 -qboolean SV_CanSeeBox(int numtraces, vec_t eyejitter, vec_t enlarge, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs) +qboolean SV_CanSeeBox(int numtraces, vec_t eyejitter, vec_t enlarge, vec_t entboxexpand, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs) { prvm_prog_t *prog = SVVM_prog; float pitchsign; @@ -1519,12 +1521,12 @@ qboolean SV_CanSeeBox(int numtraces, vec_t eyejitter, vec_t enlarge, vec3_t eye, eyemins[2] = eye[2] - eyejitter; eyemaxs[2] = eye[2] + eyejitter; // expand the box a little - boxmins[0] = (enlarge+1) * entboxmins[0] - enlarge * entboxmaxs[0]; - boxmaxs[0] = (enlarge+1) * entboxmaxs[0] - enlarge * entboxmins[0]; - boxmins[1] = (enlarge+1) * entboxmins[1] - enlarge * entboxmaxs[1]; - boxmaxs[1] = (enlarge+1) * entboxmaxs[1] - enlarge * entboxmins[1]; - boxmins[2] = (enlarge+1) * entboxmins[2] - enlarge * entboxmaxs[2]; - boxmaxs[2] = (enlarge+1) * entboxmaxs[2] - enlarge * entboxmins[2]; + boxmins[0] = (enlarge+1) * entboxmins[0] - enlarge * entboxmaxs[0] - entboxexpand; + boxmaxs[0] = (enlarge+1) * entboxmaxs[0] - enlarge * entboxmins[0] + entboxexpand; + boxmins[1] = (enlarge+1) * entboxmins[1] - enlarge * entboxmaxs[1] - entboxexpand; + boxmaxs[1] = (enlarge+1) * entboxmaxs[1] - enlarge * entboxmins[1] + entboxexpand; + boxmins[2] = (enlarge+1) * entboxmins[2] - enlarge * entboxmaxs[2] - entboxexpand; + boxmaxs[2] = (enlarge+1) * entboxmaxs[2] - enlarge * entboxmins[2] + entboxexpand; VectorMAM(0.5f, boxmins, 0.5f, boxmaxs, endpoints[0]); for (traceindex = 1;traceindex < numtraces;traceindex++) @@ -1729,7 +1731,7 @@ static void SV_MarkWriteEntityStateToClient(entity_state_t *s) { int eyeindex; for (eyeindex = 0;eyeindex < sv.writeentitiestoclient_numeyes;eyeindex++) - if(SV_CanSeeBox(samples, sv_cullentities_trace_eyejitter.value, enlarge, sv.writeentitiestoclient_eyes[eyeindex], ed->priv.server->cullmins, ed->priv.server->cullmaxs)) + if(SV_CanSeeBox(samples, sv_cullentities_trace_eyejitter.value, enlarge, sv_cullentities_trace_expand.value, sv.writeentitiestoclient_eyes[eyeindex], ed->priv.server->cullmins, ed->priv.server->cullmaxs)) break; if(eyeindex < sv.writeentitiestoclient_numeyes) svs.clients[sv.writeentitiestoclient_clientnumber].visibletime[s->number] = @@ -1812,7 +1814,7 @@ static void SV_AddCameraEyes(void) for(k = 0; k < sv.writeentitiestoclient_numeyes; ++k) if(eye_levels[k] <= MAX_EYE_RECURSION) { - if(SV_CanSeeBox(sv_cullentities_trace_samples.integer, sv_cullentities_trace_eyejitter.value, sv_cullentities_trace_enlarge.value, sv.writeentitiestoclient_eyes[k], mi, ma)) + if(SV_CanSeeBox(sv_cullentities_trace_samples.integer, sv_cullentities_trace_eyejitter.value, sv_cullentities_trace_enlarge.value, sv_cullentities_trace_expand.value, sv.writeentitiestoclient_eyes[k], mi, ma)) { eye_levels[sv.writeentitiestoclient_numeyes] = eye_levels[k] + 1; VectorCopy(camera_origins[j], sv.writeentitiestoclient_eyes[sv.writeentitiestoclient_numeyes]); @@ -1873,7 +1875,7 @@ static void SV_WriteEntitiesToClient(client_t *client, prvm_edict_t *clent, size vec_t predtime = bound(0, host_client->ping, sv_cullentities_trace_prediction_time.value); vec3_t predeye; VectorMA(eye, predtime, PRVM_serveredictvector(camera, velocity), predeye); - if (SV_CanSeeBox(1, 0, 0, eye, predeye, predeye)) + if (SV_CanSeeBox(1, 0, 0, 0, eye, predeye, predeye)) { VectorCopy(predeye, sv.writeentitiestoclient_eyes[sv.writeentitiestoclient_numeyes]); sv.writeentitiestoclient_numeyes++; -- 2.39.2