qbsp: refactor writing of leafs, nodes, marksurfaces lump

- only support bsp29 for now
This commit is contained in:
Eric Wasylishen 2021-08-22 22:51:47 -06:00
parent 24fc2ffc6a
commit 382a725f2b
3 changed files with 42 additions and 74 deletions

View File

@ -156,6 +156,9 @@ typedef struct mapdata_s {
// Final, exported data // Final, exported data
std::vector<texinfo_t> exported_texinfos; // FIXME: change to gtexinfo_t std::vector<texinfo_t> exported_texinfos; // FIXME: change to gtexinfo_t
std::vector<dplane_t> exported_planes; std::vector<dplane_t> exported_planes;
std::vector<bsp29_dleaf_t> exported_leafs_bsp29; // FIXME: change to generic leaf
std::vector<bsp29_dnode_t> exported_nodes_bsp29; // FIXME: change to generic node
std::vector<uint16_t> exported_marksurfaces; // FIXME: change type to generic
// helpers // helpers
std::string texinfoTextureName(int texinfo) const { std::string texinfoTextureName(int texinfo) const {

View File

@ -294,13 +294,13 @@ WriteBSPFile(void)
Error("Failure writing to file"); Error("Failure writing to file");
AddLumpFromBuffer(f, LUMP_PLANES, map.exported_planes.data(), map.exported_planes.size() * sizeof(map.exported_planes[0])); AddLumpFromBuffer(f, LUMP_PLANES, map.exported_planes.data(), map.exported_planes.size() * sizeof(map.exported_planes[0]));
AddLump(f, LUMP_LEAFS); AddLumpFromBuffer(f, LUMP_LEAFS, map.exported_leafs_bsp29.data(), map.exported_leafs_bsp29.size() * sizeof(map.exported_leafs_bsp29[0]));
AddLump(f, LUMP_VERTEXES); AddLump(f, LUMP_VERTEXES);
AddLump(f, LUMP_NODES); AddLumpFromBuffer(f, LUMP_NODES, map.exported_nodes_bsp29.data(), map.exported_nodes_bsp29.size() * sizeof(map.exported_nodes_bsp29[0]));
AddLumpFromBuffer(f, LUMP_TEXINFO, map.exported_texinfos.data(), map.exported_texinfos.size() * sizeof(map.exported_texinfos[0])); AddLumpFromBuffer(f, LUMP_TEXINFO, map.exported_texinfos.data(), map.exported_texinfos.size() * sizeof(map.exported_texinfos[0]));
AddLump(f, LUMP_FACES); AddLump(f, LUMP_FACES);
AddLump(f, LUMP_CLIPNODES); AddLump(f, LUMP_CLIPNODES);
AddLump(f, LUMP_MARKSURFACES); AddLumpFromBuffer(f, LUMP_MARKSURFACES, map.exported_marksurfaces.data(), map.exported_marksurfaces.size() * sizeof(map.exported_marksurfaces[0]));
AddLump(f, LUMP_SURFEDGES); AddLump(f, LUMP_SURFEDGES);
AddLump(f, LUMP_EDGES); AddLump(f, LUMP_EDGES);
AddLump(f, LUMP_MODELS); AddLump(f, LUMP_MODELS);
@ -383,12 +383,12 @@ PrintBSPFileSizes(void)
Message(msgStat, "%8d planes %10d", static_cast<int>(map.exported_planes.size()), static_cast<int>(map.exported_planes.size()) * MemSize[BSP_PLANE]); Message(msgStat, "%8d planes %10d", static_cast<int>(map.exported_planes.size()), static_cast<int>(map.exported_planes.size()) * MemSize[BSP_PLANE]);
Message(msgStat, "%8d vertexes %10d", map.cTotal[LUMP_VERTEXES], map.cTotal[LUMP_VERTEXES] * MemSize[BSP_VERTEX]); Message(msgStat, "%8d vertexes %10d", map.cTotal[LUMP_VERTEXES], map.cTotal[LUMP_VERTEXES] * MemSize[BSP_VERTEX]);
Message(msgStat, "%8d nodes %10d", map.cTotal[LUMP_NODES], map.cTotal[LUMP_NODES] * MemSize[BSP_NODE]); Message(msgStat, "%8d nodes %10d", static_cast<int>(map.exported_nodes_bsp29.size()), static_cast<int>(map.exported_nodes_bsp29.size()) * MemSize[BSP_NODE]);
Message(msgStat, "%8d texinfo %10d", static_cast<int>(map.exported_texinfos.size()), static_cast<int>(map.exported_texinfos.size()) * MemSize[BSP_TEXINFO]); Message(msgStat, "%8d texinfo %10d", static_cast<int>(map.exported_texinfos.size()), static_cast<int>(map.exported_texinfos.size()) * MemSize[BSP_TEXINFO]);
Message(msgStat, "%8d faces %10d", map.cTotal[LUMP_FACES], map.cTotal[LUMP_FACES] * MemSize[BSP_FACE]); Message(msgStat, "%8d faces %10d", map.cTotal[LUMP_FACES], map.cTotal[LUMP_FACES] * MemSize[BSP_FACE]);
Message(msgStat, "%8d clipnodes %10d", map.cTotal[LUMP_CLIPNODES], map.cTotal[LUMP_CLIPNODES] * MemSize[BSP_CLIPNODE]); Message(msgStat, "%8d clipnodes %10d", map.cTotal[LUMP_CLIPNODES], map.cTotal[LUMP_CLIPNODES] * MemSize[BSP_CLIPNODE]);
Message(msgStat, "%8d leafs %10d", map.cTotal[LUMP_LEAFS], map.cTotal[LUMP_LEAFS] * MemSize[BSP_LEAF]); Message(msgStat, "%8d leafs %10d", static_cast<int>(map.exported_leafs_bsp29.size()), static_cast<int>(map.exported_leafs_bsp29.size()) * MemSize[BSP_LEAF]);
Message(msgStat, "%8d marksurfaces %10d", map.cTotal[LUMP_MARKSURFACES], map.cTotal[LUMP_MARKSURFACES] * MemSize[BSP_MARKSURF]); Message(msgStat, "%8d marksurfaces %10d", static_cast<int>(map.exported_marksurfaces.size()), static_cast<int>(map.exported_marksurfaces.size()) * MemSize[BSP_MARKSURF]);
Message(msgStat, "%8d surfedges %10d", map.cTotal[LUMP_SURFEDGES], map.cTotal[LUMP_SURFEDGES] * MemSize[BSP_SURFEDGE]); Message(msgStat, "%8d surfedges %10d", map.cTotal[LUMP_SURFEDGES], map.cTotal[LUMP_SURFEDGES] * MemSize[BSP_SURFEDGE]);
Message(msgStat, "%8d edges %10d", map.cTotal[LUMP_EDGES], map.cTotal[LUMP_EDGES] * MemSize[BSP_EDGE]); Message(msgStat, "%8d edges %10d", map.cTotal[LUMP_EDGES], map.cTotal[LUMP_EDGES] * MemSize[BSP_EDGE]);

View File

@ -281,7 +281,7 @@ ExportClipNodes(mapentity_t *entity, node_t *nodes, const int hullnum)
//=========================================================================== //===========================================================================
#if 0
/* /*
================== ==================
CountLeaves CountLeaves
@ -335,6 +335,7 @@ CountNodes(mapentity_t *entity, node_t *headnode)
else else
CountNodes_r(entity, headnode); CountNodes_r(entity, headnode);
} }
#endif
/* /*
================== ==================
@ -344,16 +345,8 @@ ExportLeaf
static void static void
ExportLeaf_BSP29(mapentity_t *entity, node_t *node) ExportLeaf_BSP29(mapentity_t *entity, node_t *node)
{ {
struct lumpdata *leaves = &entity->lumps[LUMP_LEAFS]; map.exported_leafs_bsp29.push_back({});
struct lumpdata *marksurfs = &entity->lumps[LUMP_MARKSURFACES]; bsp29_dleaf_t *dleaf = &map.exported_leafs_bsp29.back();
uint16_t *marksurfnums = (uint16_t *)marksurfs->data;
face_t **markfaces, *face;
bsp29_dleaf_t *dleaf;
// ptr arithmetic to get correct leaf in memory
dleaf = (bsp29_dleaf_t *)leaves->data + leaves->index;
leaves->index++;
map.cTotal[LUMP_LEAFS]++;
dleaf->contents = RemapContentsForExport(node->contents); dleaf->contents = RemapContentsForExport(node->contents);
AssertVanillaContentType(dleaf->contents); AssertVanillaContentType(dleaf->contents);
@ -372,25 +365,24 @@ ExportLeaf_BSP29(mapentity_t *entity, node_t *node)
dleaf->visofs = -1; // no vis info yet dleaf->visofs = -1; // no vis info yet
// write the marksurfaces // write the marksurfaces
dleaf->firstmarksurface = map.cTotal[LUMP_MARKSURFACES]; dleaf->firstmarksurface = static_cast<int>(map.exported_marksurfaces.size());
for (markfaces = node->markfaces; *markfaces; markfaces++) { for (face_t **markfaces = node->markfaces; *markfaces; markfaces++) {
face = *markfaces; face_t *face = *markfaces;
if (map.mtexinfos.at(face->texinfo).flags & TEX_SKIP) if (map.mtexinfos.at(face->texinfo).flags & TEX_SKIP)
continue; continue;
/* emit a marksurface */ /* emit a marksurface */
do { do {
marksurfnums[marksurfs->index] = face->outputnumber; map.exported_marksurfaces.push_back(face->outputnumber);
marksurfs->index++;
map.cTotal[LUMP_MARKSURFACES]++;
face = face->original; /* grab tjunction split faces */ face = face->original; /* grab tjunction split faces */
} while (face); } while (face);
} }
dleaf->nummarksurfaces = dleaf->nummarksurfaces =
map.cTotal[LUMP_MARKSURFACES] - dleaf->firstmarksurface; static_cast<int>(map.exported_marksurfaces.size()) - dleaf->firstmarksurface;
} }
#if 0
static void static void
ExportLeaf_BSP2(mapentity_t *entity, node_t *node) ExportLeaf_BSP2(mapentity_t *entity, node_t *node)
{ {
@ -490,6 +482,7 @@ ExportLeaf_BSP2rmq(mapentity_t *entity, node_t *node)
dleaf->nummarksurfaces = dleaf->nummarksurfaces =
map.cTotal[LUMP_MARKSURFACES] - dleaf->firstmarksurface; map.cTotal[LUMP_MARKSURFACES] - dleaf->firstmarksurface;
} }
#endif
/* /*
================== ==================
@ -499,13 +492,13 @@ ExportDrawNodes
static void static void
ExportDrawNodes_BSP29(mapentity_t *entity, node_t *node) ExportDrawNodes_BSP29(mapentity_t *entity, node_t *node)
{ {
struct lumpdata *nodes = &entity->lumps[LUMP_NODES];
bsp29_dnode_t *dnode; bsp29_dnode_t *dnode;
int i; int i;
dnode = (bsp29_dnode_t *)nodes->data + nodes->index; const size_t ourNodeIndex = map.exported_nodes_bsp29.size();
nodes->index++; map.exported_nodes_bsp29.push_back({});
map.cTotal[LUMP_NODES]++;
dnode = &map.exported_nodes_bsp29[ourNodeIndex];
// VectorCopy doesn't work since dest are shorts // VectorCopy doesn't work since dest are shorts
dnode->mins[0] = (short)node->mins[0]; dnode->mins[0] = (short)node->mins[0];
@ -525,7 +518,8 @@ ExportDrawNodes_BSP29(mapentity_t *entity, node_t *node)
if (node->children[i]->contents == CONTENTS_SOLID) if (node->children[i]->contents == CONTENTS_SOLID)
dnode->children[i] = -1; dnode->children[i] = -1;
else { else {
int childnum = -(map.cTotal[LUMP_LEAFS] + 1); int nextLeafIndex = static_cast<int>(map.exported_leafs_bsp29.size());
int childnum = -(nextLeafIndex + 1);
if (childnum < INT16_MIN) { if (childnum < INT16_MIN) {
Error("Map exceeds BSP29 node/leaf limit. Recompile with -bsp2 flag."); Error("Map exceeds BSP29 node/leaf limit. Recompile with -bsp2 flag.");
} }
@ -533,12 +527,16 @@ ExportDrawNodes_BSP29(mapentity_t *entity, node_t *node)
ExportLeaf_BSP29(entity, node->children[i]); ExportLeaf_BSP29(entity, node->children[i]);
} }
} else { } else {
int childnum = map.cTotal[LUMP_NODES]; int childnum = static_cast<int>(map.exported_nodes_bsp29.size());
if (childnum > INT16_MAX) { if (childnum > INT16_MAX) {
Error("Map exceeds BSP29 node/leaf limit. Recompile with -bsp2 flag."); Error("Map exceeds BSP29 node/leaf limit. Recompile with -bsp2 flag.");
} }
dnode->children[i] = childnum; dnode->children[i] = childnum;
ExportDrawNodes_BSP29(entity, node->children[i]); ExportDrawNodes_BSP29(entity, node->children[i]);
// Important: our dnode pointer may be invalid after the recursive call, if the vector got resized.
// So re-set the pointer.
dnode = &map.exported_nodes_bsp29[ourNodeIndex];
} }
} }
@ -550,6 +548,7 @@ ExportDrawNodes_BSP29(mapentity_t *entity, node_t *node)
Q_assert(dnode->children[0] != dnode->children[1]); Q_assert(dnode->children[0] != dnode->children[1]);
} }
#if 0
static void static void
ExportDrawNodes_BSP2(mapentity_t *entity, node_t *node) ExportDrawNodes_BSP2(mapentity_t *entity, node_t *node)
{ {
@ -633,6 +632,7 @@ ExportDrawNodes_BSP2rmq(mapentity_t *entity, node_t *node)
Q_assert(!(dnode->children[0] == -1 && dnode->children[1] == -1)); Q_assert(!(dnode->children[0] == -1 && dnode->children[1] == -1));
Q_assert(dnode->children[0] != dnode->children[1]); Q_assert(dnode->children[0] != dnode->children[1]);
} }
#endif
/* /*
================== ==================
@ -644,63 +644,28 @@ ExportDrawNodes(mapentity_t *entity, node_t *headnode, int firstface)
{ {
int i; int i;
dmodel_t *dmodel; dmodel_t *dmodel;
struct lumpdata *nodes = &entity->lumps[LUMP_NODES];
struct lumpdata *leaves = &entity->lumps[LUMP_LEAFS];
struct lumpdata *marksurfs = &entity->lumps[LUMP_MARKSURFACES];
// Allocate a model // Allocate a model
entity->lumps[LUMP_MODELS].data = AllocMem(BSP_MODEL, 1, true); entity->lumps[LUMP_MODELS].data = AllocMem(BSP_MODEL, 1, true);
entity->lumps[LUMP_MODELS].count = 1; entity->lumps[LUMP_MODELS].count = 1;
// Get a feel for how many of these things there are.
CountNodes(entity, headnode);
// emit a model // emit a model
nodes->data = AllocMem(BSP_NODE, nodes->count, true);
leaves->data = AllocMem(BSP_LEAF, leaves->count, true);
marksurfs->data = AllocMem(BSP_MARKSURF, marksurfs->count, true);
/*
* Set leaf 0 properly (must be solid). cLeaves etc incremented in
* BeginBSPFile.
*/
if (options.BSPVersion == BSP2VERSION) {
bsp2_dleaf_t *leaf = (bsp2_dleaf_t *)pWorldEnt()->lumps[LUMP_LEAFS].data;
leaf->contents = CONTENTS_SOLID;
} else if (options.BSPVersion == BSP2RMQVERSION) {
bsp2rmq_dleaf_t *leaf = (bsp2rmq_dleaf_t *)pWorldEnt()->lumps[LUMP_LEAFS].data;
leaf->contents = CONTENTS_SOLID;
} else {
bsp29_dleaf_t *leaf = (bsp29_dleaf_t *)pWorldEnt()->lumps[LUMP_LEAFS].data;
leaf->contents = CONTENTS_SOLID;
}
dmodel = (dmodel_t *)entity->lumps[LUMP_MODELS].data; dmodel = (dmodel_t *)entity->lumps[LUMP_MODELS].data;
dmodel->headnode[0] = map.cTotal[LUMP_NODES]; dmodel->headnode[0] = static_cast<int>(map.exported_nodes_bsp29.size());
dmodel->firstface = firstface; dmodel->firstface = firstface;
dmodel->numfaces = map.cTotal[LUMP_FACES] - firstface; dmodel->numfaces = map.cTotal[LUMP_FACES] - firstface;
if (options.BSPVersion == BSP2VERSION) { const size_t mapleafsAtStart = map.exported_leafs_bsp29.size();
if (headnode->contents < 0)
ExportLeaf_BSP2(entity, headnode); {
else
ExportDrawNodes_BSP2(entity, headnode);
} else if (options.BSPVersion == BSP2RMQVERSION) {
if (headnode->contents < 0)
ExportLeaf_BSP2rmq(entity, headnode);
else
ExportDrawNodes_BSP2rmq(entity, headnode);
} else {
if (headnode->contents < 0) if (headnode->contents < 0)
ExportLeaf_BSP29(entity, headnode); ExportLeaf_BSP29(entity, headnode);
else else
ExportDrawNodes_BSP29(entity, headnode); ExportDrawNodes_BSP29(entity, headnode);
} }
/* Not counting initial vis leaf */ // count how many leafs were exported by the above calls
dmodel->visleafs = leaves->count; dmodel->visleafs = static_cast<int>(map.exported_leafs_bsp29.size() - mapleafsAtStart);
if (entity == pWorldEnt())
dmodel->visleafs--;
/* remove the headnode padding */ /* remove the headnode padding */
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
@ -725,9 +690,9 @@ BeginBSPFile(void)
map.cTotal[LUMP_EDGES]++; map.cTotal[LUMP_EDGES]++;
// Leave room for leaf 0 (must be solid) // Leave room for leaf 0 (must be solid)
pWorldEnt()->lumps[LUMP_LEAFS].count++; map.exported_leafs_bsp29.push_back({});
pWorldEnt()->lumps[LUMP_LEAFS].index++; map.exported_leafs_bsp29.back().contents = CONTENTS_SOLID;
map.cTotal[LUMP_LEAFS]++; Q_assert(map.exported_leafs_bsp29.size() == 1);
} }
/* /*