From 0ec879fa3fe3ded64f523cbb977bc0a858a5b536 Mon Sep 17 00:00:00 2001
From: havoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
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.5