From e3444b726f8f4ecd5320a793481e0c1e653f6c54 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 20 Mar 2021 12:00:40 +0900 Subject: [PATCH] [model] Add a re-entrant Mod_LeafPVS Double benefit, actually: faster when building a fat PVS (don't need to copy as much) and can be used in multiple threads. Also, default visiblity can be set, and the buffer size has its own macro. --- include/QF/bspfile.h | 2 ++ include/QF/model.h | 7 ++++++- libs/models/brush/model_brush.c | 36 +++++++++++++++++++++------------ nq/source/sv_main.c | 2 +- nq/source/sv_pr_cmds.c | 2 +- qw/source/sv_ents.c | 2 +- qw/source/sv_pr_cmds.c | 2 +- tools/qfvis/source/qfvis.c | 2 +- 8 files changed, 36 insertions(+), 19 deletions(-) diff --git a/include/QF/bspfile.h b/include/QF/bspfile.h index 0d32c09e8..27648f297 100644 --- a/include/QF/bspfile.h +++ b/include/QF/bspfile.h @@ -42,6 +42,8 @@ #define MAX_MAP_FACES 65535 // format limit (u16) #define MAX_MAP_MARKSURFACES 65535 // format limit (u16) +#define MAP_PVS_BYTES (MAX_MAP_LEAFS / 8) + //============================================================================= #define BSPVERSION 29 diff --git a/include/QF/model.h b/include/QF/model.h index b65a5ad18..0a7069d3f 100644 --- a/include/QF/model.h +++ b/include/QF/model.h @@ -432,7 +432,12 @@ model_t *Mod_ForName (const char *name, qboolean crash); void Mod_TouchModel (const char *name); // brush specific mleaf_t *Mod_PointInLeaf (const vec3_t p, model_t *model) __attribute__((pure)); -byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model); +byte *Mod_LeafPVS (const mleaf_t *leaf, const model_t *model); + +// NOTE: the buffer pointed to by out must be at least MAP_PVS_BYTES in size +void Mod_LeafPVS_r (const mleaf_t *leaf, const model_t *model, byte defvis, + byte *out); + void Mod_Print (void); extern struct cvar_s *gl_mesh_cache; diff --git a/libs/models/brush/model_brush.c b/libs/models/brush/model_brush.c index b18de9076..6270de72b 100644 --- a/libs/models/brush/model_brush.c +++ b/libs/models/brush/model_brush.c @@ -55,7 +55,7 @@ #include "compat.h" #include "mod_internal.h" -static byte mod_novis[MAX_MAP_LEAFS / 8]; +static byte mod_novis[MAP_PVS_BYTES]; VISIBLE cvar_t *gl_sky_divide; //FIXME visibility? VISIBLE int mod_lightmap_bytes = 1; //FIXME should this be visible? @@ -85,22 +85,21 @@ Mod_PointInLeaf (const vec3_t p, model_t *model) return NULL; // never reached } -static inline byte * -Mod_DecompressVis (byte * in, mod_brush_t *brush) +static inline void +Mod_DecompressVis (const byte *in, const mod_brush_t *brush, byte defvis, + byte *out) { - static byte decompressed[MAX_MAP_LEAFS / 8]; - byte *out; + byte *start = out; int row, c; row = (brush->numleafs + 7) >> 3; - out = decompressed; if (!in) { // no vis info, so make all visible while (row) { - *out++ = 0xff; + *out++ = defvis; row--; } - return decompressed; + return; } do { @@ -115,21 +114,32 @@ Mod_DecompressVis (byte * in, mod_brush_t *brush) *out++ = 0; c--; } - } while (out - decompressed < row); - - return decompressed; + } while (out - start < row); } VISIBLE byte * -Mod_LeafPVS (mleaf_t *leaf, model_t *model) +Mod_LeafPVS (const mleaf_t *leaf, const model_t *model) { + static byte decompressed[MAP_PVS_BYTES]; if (leaf == model->brush.leafs) { if (!mod_novis[0]) { memset (mod_novis, 0xff, sizeof (mod_novis)); } return mod_novis; } - return Mod_DecompressVis (leaf->compressed_vis, &model->brush); + Mod_DecompressVis (leaf->compressed_vis, &model->brush, 0xff, decompressed); + return decompressed; +} + +VISIBLE void +Mod_LeafPVS_r (const mleaf_t *leaf, const model_t *model, byte defvis, + byte *out) +{ + if (leaf == model->brush.leafs) { + memset (out, defvis, sizeof (mod_novis)); + return; + } + return Mod_DecompressVis (leaf->compressed_vis, &model->brush, defvis, out); } // BRUSHMODEL LOADING ========================================================= diff --git a/nq/source/sv_main.c b/nq/source/sv_main.c index d8a98b5b4..7d486f24b 100644 --- a/nq/source/sv_main.c +++ b/nq/source/sv_main.c @@ -389,7 +389,7 @@ SV_ClearDatagram (void) */ int fatbytes; -byte fatpvs[MAX_MAP_LEAFS / 8]; +byte fatpvs[MAP_PVS_BYTES]; static void SV_AddToFatPVS (vec3_t org, mnode_t *node) diff --git a/nq/source/sv_pr_cmds.c b/nq/source/sv_pr_cmds.c index 096010f77..0489b4f4c 100644 --- a/nq/source/sv_pr_cmds.c +++ b/nq/source/sv_pr_cmds.c @@ -539,7 +539,7 @@ PF_checkpos (progs_t *pr) { } -byte checkpvs[MAX_MAP_LEAFS / 8]; +byte checkpvs[MAP_PVS_BYTES]; static int PF_newcheckclient (progs_t *pr, int check) diff --git a/qw/source/sv_ents.c b/qw/source/sv_ents.c index ccbf9278b..5538de54b 100644 --- a/qw/source/sv_ents.c +++ b/qw/source/sv_ents.c @@ -54,7 +54,7 @@ when the bob crosses a waterline. */ -byte fatpvs[MAX_MAP_LEAFS / 8]; +byte fatpvs[MAP_PVS_BYTES]; int fatbytes; diff --git a/qw/source/sv_pr_cmds.c b/qw/source/sv_pr_cmds.c index b8dc58de0..b30664a76 100644 --- a/qw/source/sv_pr_cmds.c +++ b/qw/source/sv_pr_cmds.c @@ -460,7 +460,7 @@ PF_checkpos (progs_t *pr) { } -byte checkpvs[MAX_MAP_LEAFS / 8]; +byte checkpvs[MAP_PVS_BYTES]; static int PF_newcheckclient (progs_t *pr, int check) diff --git a/tools/qfvis/source/qfvis.c b/tools/qfvis/source/qfvis.c index 9ffb09e35..c62eabbcc 100644 --- a/tools/qfvis/source/qfvis.c +++ b/tools/qfvis/source/qfvis.c @@ -613,7 +613,7 @@ void ClusterFlow (int clusternum) { set_t *visclusters; - byte compressed[MAX_MAP_LEAFS / 8]; + byte compressed[MAP_PVS_BYTES]; byte *outbuffer; int numvis, i; cluster_t *cluster;