bsputils: prototype DecompressAllVis

This commit is contained in:
Eric Wasylishen 2023-01-08 23:51:00 -07:00
parent 512ad03153
commit 9c46e7f4da
2 changed files with 72 additions and 0 deletions

View File

@ -603,6 +603,16 @@ size_t DecompressedVisSize(const mbsp_t *bsp)
return (bsp->dmodels[0].visleafs + 7) / 8; return (bsp->dmodels[0].visleafs + 7) / 8;
} }
int VisleafToLeafnum(int visleaf)
{
return visleaf + 1;
}
int LeafnumToVisleaf(int leafnum)
{
return leafnum - 1;
}
// from DarkPlaces (Mod_Q1BSP_DecompressVis) // from DarkPlaces (Mod_Q1BSP_DecompressVis)
void DecompressVis(const uint8_t *in, const uint8_t *inend, uint8_t *out, uint8_t *outend) void DecompressVis(const uint8_t *in, const uint8_t *inend, uint8_t *out, uint8_t *outend)
{ {
@ -645,6 +655,64 @@ void DecompressVis(const uint8_t *in, const uint8_t *inend, uint8_t *out, uint8_
} }
} }
/**
* Decompress visdata for the entire map, and returns a map of:
*
* - Q2: cluster number to decompressed visdata
* - Q1/others: visofs to decompressed visdata
*
* Q1 uses visofs as the map key, rather than e.g. visleaf number or leaf number, because if func_detail is in use,
* many leafs will share the same visofs. This avoids storing the same visdata redundantly.
*/
std::unordered_map<int, std::vector<uint8_t>> DecompressAllVis(const mbsp_t *bsp, bool trans_water)
{
std::unordered_map<int, std::vector<uint8_t>> result;
const size_t decompressed_size = DecompressedVisSize(bsp);
if (bsp->loadversion->game->id == GAME_QUAKE_II) {
const int num_clusters = bsp->dvis.bit_offsets.size();
for (int cluster = 0; cluster < num_clusters; ++cluster) {
if (bsp->dvis.get_bit_offset(VIS_PVS, cluster) >= bsp->dvis.bits.size()) {
logging::print("DecompressAllVis: invalid visofs for cluster {}\n", cluster);
continue;
}
std::vector<uint8_t> decompressed(decompressed_size);
DecompressVis(bsp->dvis.bits.data() + bsp->dvis.get_bit_offset(VIS_PVS, cluster),
bsp->dvis.bits.data() + bsp->dvis.bits.size(), decompressed.data(), decompressed.data() + decompressed.size());
result[cluster] = std::move(decompressed);
}
} else {
for (int leafnum = 0; leafnum < bsp->dleafs.size(); ++leafnum) {
auto &leaf = bsp->dleafs[leafnum];
if (leaf.visofs < 0) {
continue;
}
const int map_key = leaf.visofs;
if (result.find(map_key) != result.end()) {
// already decompressed this cluster
continue;
}
if (leaf.visofs >= bsp->dvis.bits.size()) {
logging::print("DecompressAllVis: invalid visofs for leaf {}\n", leafnum);
continue;
}
std::vector<uint8_t> decompressed(decompressed_size);
DecompressVis(bsp->dvis.bits.data() + leaf.visofs,
bsp->dvis.bits.data() + bsp->dvis.bits.size(), decompressed.data(), decompressed.data() + decompressed.size());
result[map_key] = std::move(decompressed);
}
}
return result;
}
bspx_decoupled_lm_perface BSPX_DecoupledLM(const bspxentries_t &entries, int face_num) bspx_decoupled_lm_perface BSPX_DecoupledLM(const bspxentries_t &entries, int face_num)
{ {
auto &lump_bytes = entries.at("DECOUPLED_LM"); auto &lump_bytes = entries.at("DECOUPLED_LM");

View File

@ -29,6 +29,7 @@
#include <iterator> #include <iterator>
#include <string> #include <string>
#include <vector> #include <vector>
#include <unordered_map>
const dmodelh2_t *BSP_GetWorldModel(const mbsp_t *bsp); const dmodelh2_t *BSP_GetWorldModel(const mbsp_t *bsp);
int Face_GetNum(const mbsp_t *bsp, const mface_t *f); int Face_GetNum(const mbsp_t *bsp, const mface_t *f);
@ -107,7 +108,10 @@ void Face_DebugPrint(const mbsp_t *bsp, const mface_t *face);
void CompressRow(const uint8_t *vis, const size_t numbytes, std::back_insert_iterator<std::vector<uint8_t>> it); void CompressRow(const uint8_t *vis, const size_t numbytes, std::back_insert_iterator<std::vector<uint8_t>> it);
size_t DecompressedVisSize(const mbsp_t *bsp); size_t DecompressedVisSize(const mbsp_t *bsp);
int VisleafToLeafnum(int visleaf);
int LeafnumToVisleaf(int leafnum);
void DecompressVis(const uint8_t *in, const uint8_t *inend, uint8_t *out, uint8_t *outend); void DecompressVis(const uint8_t *in, const uint8_t *inend, uint8_t *out, uint8_t *outend);
std::unordered_map<int, std::vector<uint8_t>> DecompressAllVis(const mbsp_t *bsp, bool trans_water = false);
bspx_decoupled_lm_perface BSPX_DecoupledLM(const bspxentries_t &entries, int face_num); bspx_decoupled_lm_perface BSPX_DecoupledLM(const bspxentries_t &entries, int face_num);