decompile: add a simplifed --decompile-geomonly mode

This commit is contained in:
Eric Wasylishen 2021-02-07 00:30:49 -07:00
parent c6d389ce24
commit fcb0da5190
3 changed files with 48 additions and 8 deletions

View File

@ -529,7 +529,8 @@ main(int argc, char **argv)
printf("---- bsputil / ericw-tools " stringify(ERICWTOOLS_VERSION) " ----\n");
if (argc == 1) {
printf("usage: bsputil [--extract-entities] [--extract-textures] [--convert bsp29|bsp2|bsp2rmq|q2bsp] [--check] [--modelinfo]\n"
"[--check] [--compare otherbsp] [--findfaces x y z nx ny nz] [--settexinfo facenum texinfonum] [--decompile] bspfile\n");
"[--check] [--compare otherbsp] [--findfaces x y z nx ny nz] [--settexinfo facenum texinfonum]\n"
"[--decompile] [--decompile-geomonly] bspfile\n");
exit(1);
}
@ -676,7 +677,9 @@ main(int argc, char **argv)
WriteBSPFile(source, &bspdata);
return 0;
} else if (!strcmp(argv[i], "--decompile")) {
} else if (!strcmp(argv[i], "--decompile") || !strcmp(argv[i], "--decompile-geomonly")) {
const bool geomOnly = !strcmp(argv[i], "--decompile-geomonly");
StripExtension(source);
DefaultExtension(source, "-decompile.map");
printf("-> writing %s... ", source);
@ -685,7 +688,10 @@ main(int argc, char **argv)
if (!f)
Error("couldn't open %s for writing\n", source);
DecompileBSP(bsp, f);
decomp_options options;
options.geometryOnly = geomOnly;
DecompileBSP(bsp, options, f);
fclose(f);
return 0;

View File

@ -632,6 +632,26 @@ DecompileLeaf(const std::vector<decomp_plane_t>* planestack, const mbsp_t *bsp,
result->push_back({*planestack, leaf});
}
static std::string
DecompileLeafTaskGeometryOnly(const mbsp_t *bsp, const leaf_decompile_task& task)
{
const mleaf_t *leaf = task.leaf;
fmt::memory_buffer file;
fmt::format_to(file, "{{\n");
for (const auto& side : task.allPlanes) {
PrintPlanePoints(bsp, side, file);
// print a default face
fmt::format_to(file, " {} ", DefaultTextureForContents(leaf->contents).c_str());
WriteNullTexdef(bsp, file);
fmt::format_to(file, "\n");
}
fmt::format_to(file, "}}\n");
return fmt::to_string(file);
}
static std::string
DecompileLeafTask(const mbsp_t *bsp, const leaf_decompile_task& task)
{
@ -767,7 +787,7 @@ AddMapBoundsToStack(std::vector<decomp_plane_t>* planestack, const mbsp_t *bsp,
}
static void
DecompileEntity(const mbsp_t *bsp, FILE* file, const entdict_t& dict, bool isWorld)
DecompileEntity(const mbsp_t *bsp, const decomp_options& options, FILE* file, const entdict_t& dict, bool isWorld)
{
// we use -1 to indicate it's not a brush model
int modelNum = -1;
@ -811,7 +831,11 @@ DecompileEntity(const mbsp_t *bsp, FILE* file, const entdict_t& dict, bool isWor
std::vector<std::string> leafStrings;
leafStrings.resize(tasks.size());
tbb::parallel_for(static_cast<size_t>(0), tasks.size(), [&](const size_t i) {
leafStrings[i] = DecompileLeafTask(bsp, tasks[i]);
if (options.geometryOnly) {
leafStrings[i] = DecompileLeafTaskGeometryOnly(bsp, tasks[i]);
} else {
leafStrings[i] = DecompileLeafTask(bsp, tasks[i]);
}
});
// finally print out the leafs
@ -824,12 +848,12 @@ DecompileEntity(const mbsp_t *bsp, FILE* file, const entdict_t& dict, bool isWor
}
void
DecompileBSP(const mbsp_t *bsp, FILE* file)
DecompileBSP(const mbsp_t *bsp, const decomp_options& options, FILE* file)
{
auto entdicts = EntData_Parse(bsp->dentdata);
for (size_t i = 0; i < entdicts.size(); ++i) {
// entity 0 is implicitly worldspawn (model 0)
DecompileEntity(bsp, file, entdicts[i], i == 0);
DecompileEntity(bsp, options, file, entdicts[i], i == 0);
}
}

View File

@ -5,4 +5,14 @@
struct mbsp_t;
struct bsp2_dnode_t;
void DecompileBSP(const mbsp_t *bsp, FILE* file);
struct decomp_options {
/**
* If true, use a simplified algorithm that just dumps the planes bounding each leaf,
* without attempting to reconstruct faces or discard redundant planes.
*
* For debugging (there's not much that can go wrong).
*/
bool geometryOnly = false;
};
void DecompileBSP(const mbsp_t *bsp, const decomp_options& options, FILE* file);