From 0ec879fa3fe3ded64f523cbb977bc0a858a5b536 Mon Sep 17 00:00:00 2001 From: havoc Date: Wed, 9 Mar 2005 00:24:59 +0000 Subject: [PATCH] removed R_BoxVisible and added model->brush.BoxTouchingVisibleLeafs for more flexibility git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@5069 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rmain.c | 92 ++++++++++++++++++-------------------------------- model_brush.c | 49 +++++++++++++++++++++++++++ model_shared.h | 1 + render.h | 1 - 4 files changed, 82 insertions(+), 61 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index 253ad269..8e7fab34 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -418,56 +418,6 @@ int R_CullBox(const vec3_t mins, const vec3_t maxs) return false; } -int R_BoxVisible(const vec3_t mins, const vec3_t maxs) -{ - int side, nodestackindex = 0; - mnode_t *node, *nodestack[1024]; - if (R_CullBox(mins, maxs)) - return false; - if (!r_refdef.worldmodel || !r_refdef.worldmodel->brush.data_nodes) - return true; - node = r_refdef.worldmodel->brush.data_nodes; - for (;;) - { - if (node->plane) - { - // node - recurse down the BSP tree - side = BoxOnPlaneSide(mins, maxs, node->plane) - 1; - if (side < 2) - { - // box is on one side of plane, take that path - node = node->children[side]; - } - else - { - // box crosses plane, take one path and remember the other - if (nodestackindex < 1024) - nodestack[nodestackindex++] = node->children[0]; - node = node->children[1]; - } - } - else - { - // leaf - check leaf visibility - if (r_worldleafvisible[(mleaf_t *)node - r_refdef.worldmodel->brush.data_leafs]) - { - // it is visible, return immediately with the news - return true; - } - else - { - // nothing to see here, try another path we didn't take earlier - if (nodestackindex == 0) - break; - node = nodestack[--nodestackindex]; - } - } - } - // it is not visible - return false; -} - - //================================================================================== static void R_MarkEntities (void) @@ -479,18 +429,40 @@ static void R_MarkEntities (void) return; renderimask = envmap ? (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL) : (chase_active.integer ? 0 : RENDER_EXTERIORMODEL); - for (i = 0;i < r_refdef.numentities;i++) + if (r_refdef.worldmodel && r_refdef.worldmodel->brush.BoxTouchingVisibleLeafs) { - ent = r_refdef.entities[i]; - Mod_CheckLoaded(ent->model); - // some of the renderer still relies on origin... - Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin); - // some of the renderer still relies on scale... - ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix); - if (!(ent->flags & renderimask) && ((ent->effects & EF_NODEPTHTEST) ? R_CullBox(ent->mins, ent->maxs) : R_BoxVisible(ent->mins, ent->maxs))) + // worldmodel can check visibility + for (i = 0;i < r_refdef.numentities;i++) { - R_UpdateEntLights(ent); - ent->visframe = r_framecount; + ent = r_refdef.entities[i]; + Mod_CheckLoaded(ent->model); + // some of the renderer still relies on origin... + Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin); + // some of the renderer still relies on scale... + ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix); + if (!(ent->flags & renderimask) && !R_CullBox(ent->mins, ent->maxs) && ((ent->effects & EF_NODEPTHTEST) || r_refdef.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.worldmodel, r_worldleafvisible, ent->mins, ent->maxs))) + { + R_UpdateEntLights(ent); + ent->visframe = r_framecount; + } + } + } + else + { + // no worldmodel or it can't check visibility + for (i = 0;i < r_refdef.numentities;i++) + { + ent = r_refdef.entities[i]; + Mod_CheckLoaded(ent->model); + // some of the renderer still relies on origin... + Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin); + // some of the renderer still relies on scale... + ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix); + if (!(ent->flags & renderimask) && !R_CullBox(ent->mins, ent->maxs) && (ent->effects & EF_NODEPTHTEST)) + { + R_UpdateEntLights(ent); + ent->visframe = r_framecount; + } } } } diff --git a/model_brush.c b/model_brush.c index f4b3ca56..b7d079a5 100644 --- a/model_brush.c +++ b/model_brush.c @@ -157,6 +157,51 @@ static int Mod_Brush_BoxTouchingPVS(model_t *model, const qbyte *pvs, const vec3 return false; } +static int Mod_Brush_BoxTouchingVisibleLeafs(model_t *model, const qbyte *visibleleafs, const vec3_t mins, const vec3_t maxs) +{ + int side, nodestackindex = 0; + mnode_t *node, *nodestack[1024]; + node = model->brush.data_nodes; + for (;;) + { + if (node->plane) + { + // node - recurse down the BSP tree + side = BoxOnPlaneSide(mins, maxs, node->plane) - 1; + if (side < 2) + { + // box is on one side of plane, take that path + node = node->children[side]; + } + else + { + // box crosses plane, take one path and remember the other + if (nodestackindex < 1024) + nodestack[nodestackindex++] = node->children[0]; + node = node->children[1]; + } + } + else + { + // leaf - check if it is visible + if (visibleleafs[(mleaf_t *)node - model->brush.data_leafs]) + { + // it is visible, return immediately with the news + return true; + } + else + { + // nothing to see here, try another path we didn't take earlier + if (nodestackindex == 0) + break; + node = nodestack[--nodestackindex]; + } + } + } + // it is not visible + return false; +} + typedef struct findnonsolidlocationinfo_s { vec3_t center; @@ -2910,6 +2955,7 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer) mod->brush.GetPVS = Mod_Q1BSP_GetPVS; mod->brush.FatPVS = Mod_Q1BSP_FatPVS; mod->brush.BoxTouchingPVS = Mod_Brush_BoxTouchingPVS; + mod->brush.BoxTouchingVisibleLeafs = Mod_Brush_BoxTouchingVisibleLeafs; mod->brush.LightPoint = Mod_Q1BSP_LightPoint; mod->brush.FindNonSolidLocation = Mod_Q1BSP_FindNonSolidLocation; mod->brush.AmbientSoundLevelsForPoint = Mod_Q1BSP_AmbientSoundLevelsForPoint; @@ -3057,6 +3103,7 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer) mod->brush.GetPVS = NULL; mod->brush.FatPVS = NULL; mod->brush.BoxTouchingPVS = NULL; + mod->brush.BoxTouchingVisibleLeafs = NULL; mod->brush.LightPoint = NULL; mod->brush.AmbientSoundLevelsForPoint = NULL; } @@ -5458,6 +5505,7 @@ void Mod_Q3BSP_Load(model_t *mod, void *buffer) mod->brush.GetPVS = Mod_Q3BSP_GetPVS; mod->brush.FatPVS = Mod_Q3BSP_FatPVS; mod->brush.BoxTouchingPVS = Mod_Brush_BoxTouchingPVS; + mod->brush.BoxTouchingVisibleLeafs = Mod_Brush_BoxTouchingVisibleLeafs; mod->brush.LightPoint = Mod_Q3BSP_LightPoint; mod->brush.FindNonSolidLocation = Mod_Q3BSP_FindNonSolidLocation; //mod->DrawSky = R_Q3BSP_DrawSky; @@ -5534,6 +5582,7 @@ void Mod_Q3BSP_Load(model_t *mod, void *buffer) mod->brush.GetPVS = NULL; mod->brush.FatPVS = NULL; mod->brush.BoxTouchingPVS = NULL; + mod->brush.BoxTouchingVisibleLeafs = NULL; mod->brush.LightPoint = NULL; mod->brush.FindNonSolidLocation = Mod_Q3BSP_FindNonSolidLocation; } diff --git a/model_shared.h b/model_shared.h index 3e3e218d..245d51bf 100644 --- a/model_shared.h +++ b/model_shared.h @@ -239,6 +239,7 @@ typedef struct model_brush_s qbyte *(*GetPVS)(struct model_s *model, const vec3_t p); int (*FatPVS)(struct model_s *model, const vec3_t org, vec_t radius, qbyte *pvsbuffer, int pvsbufferlength); int (*BoxTouchingPVS)(struct model_s *model, const qbyte *pvs, const vec3_t mins, const vec3_t maxs); + int (*BoxTouchingVisibleLeafs)(struct model_s *model, const qbyte *visibleleafs, const vec3_t mins, const vec3_t maxs); void (*LightPoint)(struct model_s *model, const vec3_t p, vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal); void (*FindNonSolidLocation)(struct model_s *model, const vec3_t in, vec3_t out, vec_t radius); // these are actually only found on brushq1, but NULL is handled gracefully diff --git a/render.h b/render.h index 268d1703..80f1a2b2 100644 --- a/render.h +++ b/render.h @@ -149,7 +149,6 @@ void R_DrawExplosions(void); #define gl_alpha_format 4 int R_CullBox(const vec3_t mins, const vec3_t maxs); -int R_BoxVisible(const vec3_t mins, const vec3_t maxs); extern qboolean fogenabled; extern vec3_t fogcolor; -- 2.39.2