[model] Remove Mod_LeafPVS in favor of mix/set

The use of a static set makes Mod_LeafPVS not thread safe and also means
that the set is not usable with the set iterators after going to a
smaller map from a larger map.
This commit is contained in:
Bill Currie 2023-08-05 11:51:01 +09:00
parent 7294a77356
commit 15d7222ebb
8 changed files with 11 additions and 47 deletions

View file

@ -435,8 +435,7 @@ void Mod_TouchModel (const char *name);
void Mod_UnloadModel (model_t *model);
// brush specific
mleaf_t *Mod_PointInLeaf (vec4f_t p, const mod_brush_t *brush) __attribute__((pure));
struct set_s *Mod_LeafPVS (const mleaf_t *leaf, const mod_brush_t *brush);
struct set_s;
void Mod_LeafPVS_set (const mleaf_t *leaf, const mod_brush_t *brush,
byte defvis, struct set_s *pvs);
void Mod_LeafPVS_mix (const mleaf_t *leaf, const mod_brush_t *brush,

View file

@ -147,35 +147,6 @@ Mod_DecompressVis_mix (const byte *in, const mod_brush_t *brush, byte defvis,
} while (out - start < row);
}
VISIBLE set_t *
Mod_LeafPVS (const mleaf_t *leaf, const mod_brush_t *brush)
{
static set_t *novis;
static set_t *decompressed;
unsigned numvis = brush->visleafs;
unsigned excess = SET_SIZE (numvis) - numvis;
if (leaf == brush->leafs) {
if (!novis) {
novis = set_new_size (numvis);
}
if (!novis->map[0] || SET_SIZE (numvis) > novis->size) {
set_expand (novis, numvis);
memset (novis->map, 0xff,
SET_WORDS (novis) * sizeof (*novis->map));
novis->map[SET_WORDS (novis) - 1] &= (~SET_ZERO) >> excess;
}
return novis;
}
if (!decompressed) {
decompressed = set_new ();
}
set_expand (decompressed, numvis);
Mod_DecompressVis_set (leaf->compressed_vis, brush, 0xff, decompressed);
decompressed->map[SET_WORDS (decompressed) - 1] &= (~SET_ZERO) >> excess;
return decompressed;
}
VISIBLE void
Mod_LeafPVS_set (const mleaf_t *leaf, const mod_brush_t *brush, byte defvis,
set_t *out)

View file

@ -43,8 +43,6 @@
#include "r_internal.h"
static set_t *solid;
void
R_MarkLeavesPVS (visstate_t *visstate, const set_t *pvs)
{
@ -80,8 +78,8 @@ R_MarkLeavesPVS (visstate_t *visstate, const set_t *pvs)
void
R_MarkLeaves (visstate_t *visstate, const mleaf_t *viewleaf)
{
set_t *vis;
auto brush = visstate->brush;
set_t vis = SET_STATIC_INIT (brush->visleafs, alloca);
if (visstate->viewleaf == viewleaf && !r_novis)
return;
@ -93,15 +91,11 @@ R_MarkLeaves (visstate_t *visstate, const mleaf_t *viewleaf)
if (r_novis) {
// so vis will be recalculated when novis gets turned off
visstate->viewleaf = 0;
if (!solid) {
solid = set_new ();
set_everything (solid);
}
vis = solid;
} else {
vis = Mod_LeafPVS (viewleaf, brush);
// force use of default vis (full visibility)
viewleaf = brush->leafs;
}
R_MarkLeavesPVS (visstate, vis);
Mod_LeafPVS_set (viewleaf, brush, 0xff, &vis);
R_MarkLeavesPVS (visstate, &vis);
}
/*

View file

@ -386,7 +386,7 @@ SV_AddToFatPVS (vec4f_t org, int node_id)
if (node_id < 0) {
mleaf_t *leaf = sv.worldmodel->brush.leafs + ~node_id;
if (leaf->contents != CONTENTS_SOLID) {
set_union (fatpvs, Mod_LeafPVS (leaf, &sv.worldmodel->brush));
Mod_LeafPVS_mix (leaf, &sv.worldmodel->brush, 0xff, fatpvs);
}
return;
}

View file

@ -588,7 +588,7 @@ PF_newcheckclient (progs_t *pr, unsigned check)
if (!checkpvs) {
checkpvs = set_new_size (sv.worldmodel->brush.visleafs);
}
set_assign (checkpvs, Mod_LeafPVS (leaf, &sv.worldmodel->brush));
Mod_LeafPVS_set (leaf, &sv.worldmodel->brush, 0xff, checkpvs);
return i;
}

View file

@ -988,7 +988,7 @@ add_to_fat_pvs (vec4f_t org, int node_id, server_t *sv)
if (node_id < 0) {
mleaf_t *leaf = sv->worldmodel->brush.leafs + ~node_id;
if (leaf->contents != CONTENTS_SOLID) {
set_union (sv->fatpvs, Mod_LeafPVS (leaf, brush));
Mod_LeafPVS_mix (leaf, brush, 0xff, sv->fatpvs);
}
return;
}

View file

@ -71,7 +71,7 @@ SV_AddToFatPVS (vec4f_t org, int node_id)
if (node_id < 0) {
mleaf_t *leaf = brush->leafs + ~node_id;
if (leaf->contents != CONTENTS_SOLID) {
set_union (fatpvs, Mod_LeafPVS (leaf, brush));
Mod_LeafPVS_mix (leaf, brush, 0xff, fatpvs);
}
return;
}

View file

@ -509,7 +509,7 @@ PF_newcheckclient (progs_t *pr, int check)
if (!checkpvs) {
checkpvs = set_new_size (sv.worldmodel->brush.visleafs);
}
set_assign (checkpvs, Mod_LeafPVS (leaf, &sv.worldmodel->brush));
Mod_LeafPVS_set (leaf, &sv.worldmodel->brush, 0xff, checkpvs);
return i;
}