FreeTreePortals call missing
allow decompiling hulls (not hooked up to console yet)
This commit is contained in:
parent
027c45d608
commit
92fdff1222
|
|
@ -224,6 +224,7 @@ struct decomp_plane_t : qplane3d
|
||||||
{
|
{
|
||||||
const bsp2_dnode_t *node = nullptr; // can be nullptr
|
const bsp2_dnode_t *node = nullptr; // can be nullptr
|
||||||
const q2_dbrushside_qbism_t *source = nullptr;
|
const q2_dbrushside_qbism_t *source = nullptr;
|
||||||
|
const bsp2_dclipnode_t *clipnode = nullptr; // can be nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
// brush creation
|
// brush creation
|
||||||
|
|
@ -336,6 +337,7 @@ struct leaf_decompile_task
|
||||||
const mleaf_t *leaf = nullptr;
|
const mleaf_t *leaf = nullptr;
|
||||||
const dbrush_t *brush = nullptr;
|
const dbrush_t *brush = nullptr;
|
||||||
const dmodelh2_t *model = nullptr;
|
const dmodelh2_t *model = nullptr;
|
||||||
|
std::optional<int32_t> contents = std::nullopt; // for clipnodes
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -775,7 +777,7 @@ static compiled_brush_t DecompileLeafTaskGeometryOnly(
|
||||||
compiled_brush_t brush;
|
compiled_brush_t brush;
|
||||||
brush.source = task.brush;
|
brush.source = task.brush;
|
||||||
brush.brush_offset = brush_offset;
|
brush.brush_offset = brush_offset;
|
||||||
brush.contents = {task.brush ? task.brush->contents : task.leaf->contents};
|
brush.contents = {task.brush ? task.brush->contents : task.leaf ? task.leaf->contents : task.contents.value()};
|
||||||
|
|
||||||
brush.sides.reserve(task.allPlanes.size());
|
brush.sides.reserve(task.allPlanes.size());
|
||||||
|
|
||||||
|
|
@ -796,7 +798,7 @@ static compiled_brush_t DecompileLeafTask(
|
||||||
compiled_brush_t brush;
|
compiled_brush_t brush;
|
||||||
brush.source = task.brush;
|
brush.source = task.brush;
|
||||||
brush.brush_offset = brush_offset;
|
brush.brush_offset = brush_offset;
|
||||||
brush.contents = {task.brush ? task.brush->contents : task.leaf->contents};
|
brush.contents = {task.brush ? task.brush->contents : task.leaf ? task.leaf->contents : task.contents.value()};
|
||||||
|
|
||||||
std::vector<decomp_brush_t> finalBrushes;
|
std::vector<decomp_brush_t> finalBrushes;
|
||||||
if (bsp->loadversion->game->id == GAME_QUAKE_II && !options.ignoreBrushes) {
|
if (bsp->loadversion->game->id == GAME_QUAKE_II && !options.ignoreBrushes) {
|
||||||
|
|
@ -908,6 +910,14 @@ decomp_plane_t MakeDecompPlane(const mbsp_t *bsp, const bsp2_dnode_t *node, cons
|
||||||
front ? -dplane : dplane, node};
|
front ? -dplane : dplane, node};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
decomp_plane_t MakeClipDecompPlane(const mbsp_t *bsp, const bsp2_dclipnode_t *clipnode, const bool front)
|
||||||
|
{
|
||||||
|
const dplane_t &dplane = *BSP_GetPlane(bsp, clipnode->planenum);
|
||||||
|
|
||||||
|
return {// flip the plane if we went down the front side, since we want the outward-facing plane
|
||||||
|
front ? -dplane : dplane, nullptr, nullptr, clipnode};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Preconditions:
|
* Preconditions:
|
||||||
* - The existing path of plane side choices have been pushed onto `planestack` (but not `node`)
|
* - The existing path of plane side choices have been pushed onto `planestack` (but not `node`)
|
||||||
|
|
@ -937,6 +947,41 @@ static void DecompileNode(std::vector<decomp_plane_t> &planestack, const mbsp_t
|
||||||
handleSide(false);
|
handleSide(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void DecompileClipLeaf(const std::vector<decomp_plane_t> &planestack, const mbsp_t *bsp, const int32_t contents,
|
||||||
|
std::vector<leaf_decompile_task> &result)
|
||||||
|
{
|
||||||
|
if (contents == CONTENTS_EMPTY) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: copies the whole plane stack
|
||||||
|
result.push_back({planestack, nullptr, nullptr, nullptr, contents});
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DecompileClipNode(std::vector<decomp_plane_t> &planestack, const mbsp_t *bsp, const bsp2_dclipnode_t *node,
|
||||||
|
std::vector<leaf_decompile_task> &result)
|
||||||
|
{
|
||||||
|
auto handleSide = [&](const bool front) {
|
||||||
|
planestack.push_back(MakeClipDecompPlane(bsp, node, front));
|
||||||
|
|
||||||
|
const int32_t child = node->children[front ? 0 : 1];
|
||||||
|
|
||||||
|
if (child < 0) {
|
||||||
|
// it's a leaf on this side
|
||||||
|
DecompileClipLeaf(planestack, bsp, child, result);
|
||||||
|
} else {
|
||||||
|
// it's another node - process it recursively
|
||||||
|
DecompileClipNode(planestack, bsp, &bsp->dclipnodes[child], result);
|
||||||
|
}
|
||||||
|
|
||||||
|
planestack.pop_back();
|
||||||
|
};
|
||||||
|
|
||||||
|
// handle the front and back
|
||||||
|
handleSide(true);
|
||||||
|
handleSide(false);
|
||||||
|
}
|
||||||
|
|
||||||
static void AddMapBoundsToStack(
|
static void AddMapBoundsToStack(
|
||||||
std::vector<decomp_plane_t> &planestack, const mbsp_t *bsp, const bsp2_dnode_t *headnode)
|
std::vector<decomp_plane_t> &planestack, const mbsp_t *bsp, const bsp2_dnode_t *headnode)
|
||||||
{
|
{
|
||||||
|
|
@ -995,17 +1040,20 @@ static void DecompileEntity(
|
||||||
// the model. We're also assuming that the areaportal brushes are
|
// the model. We're also assuming that the areaportal brushes are
|
||||||
// emitted in the same order as the func_areaportal entities.
|
// emitted in the same order as the func_areaportal entities.
|
||||||
if (dict.find("classname")->second == "func_areaportal") {
|
if (dict.find("classname")->second == "func_areaportal") {
|
||||||
size_t brush_offset = std::stoull(dict.find("style")->second);
|
|
||||||
|
|
||||||
for (auto &brush : bsp->dbrushes) {
|
if (dict.has("style")) {
|
||||||
if (brush.contents & Q2_CONTENTS_AREAPORTAL) {
|
size_t brush_offset = std::stoull(dict.find("style")->second);
|
||||||
if (brush_offset == 1) {
|
|
||||||
// we'll use this one
|
for (auto &brush : bsp->dbrushes) {
|
||||||
areaportal_brush = &brush;
|
if (brush.contents & Q2_CONTENTS_AREAPORTAL) {
|
||||||
break;
|
if (brush_offset == 1) {
|
||||||
|
// we'll use this one
|
||||||
|
areaportal_brush = &brush;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
brush_offset--;
|
||||||
}
|
}
|
||||||
|
|
||||||
brush_offset--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (dict.find("classname")->second == "func_group") {
|
} else if (dict.find("classname")->second == "func_group") {
|
||||||
|
|
@ -1112,7 +1160,9 @@ static void DecompileEntity(
|
||||||
std::vector<decomp_plane_t> stack;
|
std::vector<decomp_plane_t> stack;
|
||||||
std::vector<leaf_decompile_task> tasks;
|
std::vector<leaf_decompile_task> tasks;
|
||||||
AddMapBoundsToStack(stack, bsp, headnode);
|
AddMapBoundsToStack(stack, bsp, headnode);
|
||||||
|
|
||||||
DecompileNode(stack, bsp, headnode, tasks);
|
DecompileNode(stack, bsp, headnode, tasks);
|
||||||
|
//DecompileClipNode(stack, bsp, &bsp->dclipnodes[model->headnode[1]], tasks);
|
||||||
|
|
||||||
// decompile the leafs in parallel
|
// decompile the leafs in parallel
|
||||||
compiledBrushes.resize(tasks.size());
|
compiledBrushes.resize(tasks.size());
|
||||||
|
|
|
||||||
|
|
@ -490,6 +490,7 @@ static void ProcessEntity(mapentity_t *entity, hull_index_t hullnum)
|
||||||
// fill again so PruneNodes works
|
// fill again so PruneNodes works
|
||||||
MakeTreePortals(tree.get());
|
MakeTreePortals(tree.get());
|
||||||
FillOutside(entity, tree.get(), hullnum, brushes);
|
FillOutside(entity, tree.get(), hullnum, brushes);
|
||||||
|
FreeTreePortals(tree.get());
|
||||||
PruneNodes(tree->headnode);
|
PruneNodes(tree->headnode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue