From 50740c1014432f601d9864b7d03b2cd5f2cb8588 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 27 Jul 2021 12:32:40 +0900 Subject: [PATCH] [model] Remove the confusion about numleafs The fact that numleafs did not include leaf 0 actually caused in many places due to never being sure whether to add 1. Hopefully this fixes some of the confusion. (and that comment in sv_init didn't last long :P) --- include/QF/model.h | 3 +- libs/models/brush/model_brush.c | 30 +++++++++++--------- libs/video/renderer/gl/gl_rmisc.c | 2 +- libs/video/renderer/r_bsp.c | 2 +- libs/video/renderer/r_light.c | 4 +-- libs/video/renderer/sw/sw_rmain.c | 3 +- libs/video/renderer/sw32/sw32_rmain.c | 3 +- libs/video/renderer/vulkan/vulkan_lighting.c | 13 +++++---- nq/source/sv_main.c | 4 +-- nq/source/sv_pr_cmds.c | 2 +- qw/source/sv_ents.c | 4 +-- qw/source/sv_init.c | 7 +---- qw/source/sv_pr_cmds.c | 2 +- 13 files changed, 39 insertions(+), 40 deletions(-) diff --git a/include/QF/model.h b/include/QF/model.h index 5a3b568c3..9cbc322f6 100644 --- a/include/QF/model.h +++ b/include/QF/model.h @@ -230,7 +230,8 @@ typedef struct mod_brush_s { int numplanes; plane_t *planes; - unsigned numleafs; // number of visible leafs, not counting 0 + unsigned modleafs; ///< number of leafs in model, including 0 + unsigned visleafs; ///< number of visible leafs, not counting 0 mleaf_t *leafs; int numvertexes; diff --git a/libs/models/brush/model_brush.c b/libs/models/brush/model_brush.c index c111cdfb7..ac9901c01 100644 --- a/libs/models/brush/model_brush.c +++ b/libs/models/brush/model_brush.c @@ -92,7 +92,7 @@ Mod_DecompressVis_set (const byte *in, const mod_brush_t *brush, byte defvis, byte *start = out; int row, c; - row = (brush->numleafs + 7) >> 3; + row = (brush->visleafs + 7) >> 3; if (!in) { // no vis info, so make all visible while (row) { @@ -125,7 +125,7 @@ Mod_DecompressVis_mix (const byte *in, const mod_brush_t *brush, byte defvis, byte *start = out; int row, c; - row = (brush->numleafs + 7) >> 3; + row = (brush->visleafs + 7) >> 3; if (!in) { // no vis info, so make all visible while (row) { @@ -152,7 +152,7 @@ Mod_LeafPVS (const mleaf_t *leaf, const model_t *model) { static set_t *novis; static set_t *decompressed; - unsigned numvis = model->brush.numleafs; + unsigned numvis = model->brush.visleafs; if (leaf == model->brush.leafs) { if (!novis) { @@ -180,7 +180,7 @@ VISIBLE void Mod_LeafPVS_set (const mleaf_t *leaf, const model_t *model, byte defvis, set_t *out) { - unsigned numvis = model->brush.numleafs; + unsigned numvis = model->brush.visleafs; set_expand (out, numvis); if (leaf == model->brush.leafs) { unsigned excess = SET_SIZE (numvis) - numvis; @@ -195,7 +195,7 @@ VISIBLE void Mod_LeafPVS_mix (const mleaf_t *leaf, const model_t *model, byte defvis, set_t *out) { - unsigned numvis = model->brush.numleafs; + unsigned numvis = model->brush.visleafs; set_expand (out, numvis); if (leaf == model->brush.leafs) { unsigned excess = SET_SIZE (numvis) - numvis; @@ -673,7 +673,7 @@ Mod_SetParent (mod_brush_t *brush, mnode_t *node, mnode_t *parent) static void Mod_SetLeafFlags (mod_brush_t *brush) { - for (unsigned i = 0; i < brush->numleafs; i++) { + for (unsigned i = 0; i < brush->modleafs; i++) { int flags = 0; mleaf_t *leaf = &brush->leafs[i]; for (int j = 0; j < leaf->nummarksurfaces; j++) { @@ -723,12 +723,12 @@ Mod_LoadNodes (model_t *mod, bsp_t *bsp) out->children[j] = brush->nodes + p; } else { p = ~p; - if ((unsigned) p < brush->numleafs) { + if ((unsigned) p < brush->modleafs) { out->children[j] = (mnode_t *) (brush->leafs + p); } else { Sys_Printf ("Mod_LoadNodes: invalid leaf index %i " "(file has only %i leafs)\n", p, - brush->numleafs); + brush->modleafs); //map it to the solid leaf out->children[j] = (mnode_t *)(brush->leafs); } @@ -736,11 +736,11 @@ Mod_LoadNodes (model_t *mod, bsp_t *bsp) } } - size_t size = (brush->numleafs + brush->numnodes) * sizeof (mnode_t *); - size += brush->numleafs * sizeof (int); + size_t size = (brush->modleafs + brush->numnodes) * sizeof (mnode_t *); + size += brush->modleafs * sizeof (int); brush->node_parents = Hunk_AllocName (size, mod->name); brush->leaf_parents = brush->node_parents + brush->numnodes; - brush->leaf_flags = (int *) (brush->leaf_parents + brush->numleafs); + brush->leaf_flags = (int *) (brush->leaf_parents + brush->modleafs); Mod_SetParent (brush, brush->nodes, NULL); // sets nodes and leafs Mod_SetLeafFlags (brush); } @@ -759,7 +759,7 @@ Mod_LoadLeafs (model_t *mod, bsp_t *bsp) out = Hunk_AllocName (count * sizeof (*out), mod->name); brush->leafs = out; - brush->numleafs = count; + brush->modleafs = count; // snprintf(s, sizeof (s), "maps/%s.bsp", // Info_ValueForKey(cl.serverinfo,"map")); if (!strncmp ("maps/", mod->path, 5)) @@ -1088,7 +1088,11 @@ Mod_LoadBrushModel (model_t *mod, void *buffer) mod->radius = RadiusFromBounds (mod->mins, mod->maxs); - mod->brush.numleafs = bm->visleafs; + mod->brush.visleafs = bm->visleafs; + // The bsp file has leafs for all submodes and hulls, so update the + // leaf count for this model to be the correct number (which is one + // more than the number of visible leafs) + mod->brush.modleafs = bm->visleafs + 1; if (i < mod->brush.numsubmodels - 1) { // duplicate the basic information diff --git a/libs/video/renderer/gl/gl_rmisc.c b/libs/video/renderer/gl/gl_rmisc.c index 689d38f75..c2d98b3f1 100644 --- a/libs/video/renderer/gl/gl_rmisc.c +++ b/libs/video/renderer/gl/gl_rmisc.c @@ -197,7 +197,7 @@ gl_R_NewMap (model_t *worldmodel, struct model_s **models, int num_models) R_FreeAllEntities (); // clear out efrags in case the level hasn't been reloaded - for (unsigned i = 0; i < brush->numleafs; i++) + for (unsigned i = 0; i < brush->modleafs; i++) brush->leafs[i].efrags = NULL; // Force a vis update diff --git a/libs/video/renderer/r_bsp.c b/libs/video/renderer/r_bsp.c index b7ac3614f..695f7e063 100644 --- a/libs/video/renderer/r_bsp.c +++ b/libs/video/renderer/r_bsp.c @@ -75,7 +75,7 @@ R_MarkLeaves (void) } else vis = Mod_LeafPVS (r_viewleaf, r_worldentity.renderer.model); - for (unsigned i = 0; i < brush->numleafs; i++) { + for (unsigned i = 0; i < brush->visleafs; i++) { if (set_is_member (vis, i)) { leaf = &brush->leafs[i + 1]; if ((c = leaf->nummarksurfaces)) { diff --git a/libs/video/renderer/r_light.c b/libs/video/renderer/r_light.c index 52169f05b..7debf10c1 100644 --- a/libs/video/renderer/r_light.c +++ b/libs/video/renderer/r_light.c @@ -281,13 +281,13 @@ R_MarkLights (const vec3_t lightorigin, dlight_t *light, int lightnum, maxs[0] = lightorigin[0] + radius; maxs[1] = lightorigin[1] + radius; maxs[2] = lightorigin[2] + radius; - while (leafnum < brush->numleafs) { + while (leafnum < brush->visleafs) { int b; if (!(vis_bits = *in++)) { leafnum += (*in++) * 8; continue; } - for (b = 1; b < 256 && leafnum < brush->numleafs; + for (b = 1; b < 256 && leafnum < brush->visleafs; b <<= 1, leafnum++) { int m; mleaf_t *leaf = &brush->leafs[leafnum + 1]; diff --git a/libs/video/renderer/sw/sw_rmain.c b/libs/video/renderer/sw/sw_rmain.c index 59699a8aa..f84c218b2 100644 --- a/libs/video/renderer/sw/sw_rmain.c +++ b/libs/video/renderer/sw/sw_rmain.c @@ -172,8 +172,7 @@ R_NewMap (model_t *worldmodel, struct model_s **models, int num_models) R_FreeAllEntities (); // clear out efrags in case the level hasn't been reloaded - // FIXME: is this one short? - for (unsigned i = 0; i < brush->numleafs; i++) + for (unsigned i = 0; i < brush->modleafs; i++) brush->leafs[i].efrags = NULL; if (brush->skytexture) diff --git a/libs/video/renderer/sw32/sw32_rmain.c b/libs/video/renderer/sw32/sw32_rmain.c index 2aa7f2921..6f1fee59f 100644 --- a/libs/video/renderer/sw32/sw32_rmain.c +++ b/libs/video/renderer/sw32/sw32_rmain.c @@ -187,8 +187,7 @@ sw32_R_NewMap (model_t *worldmodel, struct model_s **models, int num_models) R_FreeAllEntities (); // clear out efrags in case the level hasn't been reloaded - // FIXME: is this one short? - for (unsigned i = 0; i < brush->numleafs; i++) + for (unsigned i = 0; i < brush->modleafs; i++) brush->leafs[i].efrags = NULL; if (brush->skytexture) diff --git a/libs/video/renderer/vulkan/vulkan_lighting.c b/libs/video/renderer/vulkan/vulkan_lighting.c index f2e2b012c..ce13b7bed 100644 --- a/libs/video/renderer/vulkan/vulkan_lighting.c +++ b/libs/video/renderer/vulkan/vulkan_lighting.c @@ -71,9 +71,9 @@ static vec4f_t ref_direction = { 0, 0, 1, 0 }; static void expand_pvs (set_t *pvs, model_t *model) { - set_t base_pvs = SET_STATIC_INIT (model->brush.numleafs, alloca); + set_t base_pvs = SET_STATIC_INIT (model->brush.visleafs, alloca); set_assign (&base_pvs, pvs); - for (unsigned i = 0; i < model->brush.numleafs; i++) { + for (unsigned i = 0; i < model->brush.visleafs; i++) { if (set_is_member (&base_pvs, i)) { Mod_LeafPVS_mix (model->brush.leafs + i + 1, model, 0, pvs); } @@ -105,7 +105,7 @@ find_visible_lights (vulkan_ctx_t *ctx) Mod_LeafPVS_set (leaf, model, 0, lframe->pvs); expand_pvs (lframe->pvs, model); } - for (unsigned i = 0; i < model->brush.numleafs; i++) { + for (unsigned i = 0; i < model->brush.visleafs; i++) { if (set_is_member (lframe->pvs, i)) { flags |= model->brush.leaf_flags[i + 1]; } @@ -556,7 +556,7 @@ parse_sun (lightingctx_t *lctx, plitem_t *entity, model_t *model) //float sunlight2; vec3_t sunangle = { 0, -90, 0 }; - set_expand (lctx->sun_pvs, model->brush.numleafs); + set_expand (lctx->sun_pvs, model->brush.visleafs); set_empty (lctx->sun_pvs); sunlight = parse_float (PL_String (PL_ObjectForKey (entity, "_sunlight")), 0); @@ -577,9 +577,10 @@ parse_sun (lightingctx_t *lctx, plitem_t *entity, model_t *model) // Any leaf with sky surfaces can potentially see the sun, thus put // the sun "in" every leaf with a sky surface - for (unsigned l = 0; l < model->brush.numleafs; l++) { + // however, skip leaf 0 as it is the exterior solid leaf + for (unsigned l = 1; l < model->brush.modleafs; l++) { if (model->brush.leaf_flags[l] & SURF_DRAWSKY) { - set_add (lctx->sun_pvs, l); + set_add (lctx->sun_pvs, l - 1); //pvs is 1-based } } // any leaf visible from a leaf with a sky surface (and thus the sun) diff --git a/nq/source/sv_main.c b/nq/source/sv_main.c index eec256779..f8aace8c4 100644 --- a/nq/source/sv_main.c +++ b/nq/source/sv_main.c @@ -430,9 +430,9 @@ static set_t * SV_FatPVS (vec3_t org) { if (!fatpvs) { - fatpvs = set_new_size (sv.worldmodel->brush.numleafs); + fatpvs = set_new_size (sv.worldmodel->brush.visleafs); } - set_expand (fatpvs, sv.worldmodel->brush.numleafs); + set_expand (fatpvs, sv.worldmodel->brush.visleafs); set_empty (fatpvs); SV_AddToFatPVS (org, sv.worldmodel->brush.nodes); return fatpvs; diff --git a/nq/source/sv_pr_cmds.c b/nq/source/sv_pr_cmds.c index 4a0aa76a7..0e133a2f0 100644 --- a/nq/source/sv_pr_cmds.c +++ b/nq/source/sv_pr_cmds.c @@ -585,7 +585,7 @@ PF_newcheckclient (progs_t *pr, int check) VectorAdd (SVvector (ent, origin), SVvector (ent, view_ofs), org); leaf = Mod_PointInLeaf (org, sv.worldmodel); if (!checkpvs) { - checkpvs = set_new_size (sv.worldmodel->brush.numleafs); + checkpvs = set_new_size (sv.worldmodel->brush.visleafs); } set_assign (checkpvs, Mod_LeafPVS (leaf, sv.worldmodel)); diff --git a/qw/source/sv_ents.c b/qw/source/sv_ents.c index b7505dfb0..e38c2ca67 100644 --- a/qw/source/sv_ents.c +++ b/qw/source/sv_ents.c @@ -97,9 +97,9 @@ static set_t * SV_FatPVS (vec3_t org) { if (!fatpvs) { - fatpvs = set_new_size (sv.worldmodel->brush.numleafs); + fatpvs = set_new_size (sv.worldmodel->brush.visleafs); } - set_expand (fatpvs, sv.worldmodel->brush.numleafs); + set_expand (fatpvs, sv.worldmodel->brush.visleafs); set_empty (fatpvs); SV_AddToFatPVS (org, sv.worldmodel->brush.nodes); return fatpvs; diff --git a/qw/source/sv_init.c b/qw/source/sv_init.c index a5cd05aac..359b74570 100644 --- a/qw/source/sv_init.c +++ b/qw/source/sv_init.c @@ -254,13 +254,8 @@ SV_CalcPHS (void) int num, i; SV_Printf ("Building PHS...\n"); - //numleafs does NOT include the world-surrounding solid leaf at - //brush.leafs[0], so brush.leafs is actually [0]..[numleafs] - //however, pvs bits also do not include leaf 0 as it should not be - //able to see anything (but instead sees everything) - //FIXME make numleafs actual number of leafs? - num = sv.worldmodel->brush.numleafs + 1; + num = sv.worldmodel->brush.modleafs; sv.pvs = sv_alloc_vis_array (num); vcount = 0; for (i = 0; i < num; i++) { diff --git a/qw/source/sv_pr_cmds.c b/qw/source/sv_pr_cmds.c index 6b2b85389..f651599fb 100644 --- a/qw/source/sv_pr_cmds.c +++ b/qw/source/sv_pr_cmds.c @@ -506,7 +506,7 @@ PF_newcheckclient (progs_t *pr, int check) VectorAdd (SVvector (ent, origin), SVvector (ent, view_ofs), org); leaf = Mod_PointInLeaf (org, sv.worldmodel); if (!checkpvs) { - checkpvs = set_new_size (sv.worldmodel->brush.numleafs); + checkpvs = set_new_size (sv.worldmodel->brush.visleafs); } set_assign (checkpvs, Mod_LeafPVS (leaf, sv.worldmodel));