Merge branch 'brushbsp' of https://github.com/ericwa/ericw-tools into brushbsp
This commit is contained in:
commit
b37917c9ca
|
|
@ -3,6 +3,8 @@ target_link_libraries(bspinfo common fmt::fmt)
|
|||
|
||||
# HACK: copy .dll dependencies
|
||||
add_custom_command(TARGET bspinfo POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:TBB::tbb>" "$<TARGET_FILE_DIR:bspinfo>")
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:TBB::tbb>" "$<TARGET_FILE_DIR:bspinfo>"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:TBB::tbbmalloc>" "$<TARGET_FILE_DIR:bspinfo>"
|
||||
)
|
||||
|
||||
install(TARGETS bspinfo RUNTIME DESTINATION bin)
|
||||
|
|
|
|||
|
|
@ -4,10 +4,12 @@ set(BSPUTIL_SOURCES
|
|||
decompile.cpp)
|
||||
|
||||
add_executable(bsputil ${BSPUTIL_SOURCES})
|
||||
target_link_libraries(bsputil common TBB::tbb fmt::fmt)
|
||||
target_link_libraries(bsputil common TBB::tbb TBB::tbbmalloc fmt::fmt)
|
||||
|
||||
# HACK: copy .dll dependencies
|
||||
add_custom_command(TARGET bsputil POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:TBB::tbb>" "$<TARGET_FILE_DIR:bsputil>")
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:TBB::tbb>" "$<TARGET_FILE_DIR:bsputil>"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:TBB::tbbmalloc>" "$<TARGET_FILE_DIR:bsputil>"
|
||||
)
|
||||
|
||||
install(TARGETS bsputil RUNTIME DESTINATION bin)
|
||||
|
|
|
|||
|
|
@ -35,4 +35,4 @@ add_library(common STATIC
|
|||
${CMAKE_SOURCE_DIR}/include/common/prtfile.hh
|
||||
${CMAKE_SOURCE_DIR}/include/common/vectorutils.hh)
|
||||
|
||||
target_link_libraries(common ${CMAKE_THREAD_LIBS_INIT} TBB::tbb fmt::fmt nlohmann_json::nlohmann_json)
|
||||
target_link_libraries(common ${CMAKE_THREAD_LIBS_INIT} TBB::tbb TBB::tbbmalloc fmt::fmt nlohmann_json::nlohmann_json)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
#include <stdexcept>
|
||||
#include <optional>
|
||||
|
||||
#include <tbb/scalable_allocator.h>
|
||||
|
||||
namespace polylib
|
||||
{
|
||||
|
||||
|
|
@ -202,7 +204,7 @@ public:
|
|||
struct winding_storage_heap_t
|
||||
{
|
||||
protected:
|
||||
std::vector<qvec3d> values {};
|
||||
std::vector<qvec3d, tbb::scalable_allocator<qvec3d>> values{};
|
||||
|
||||
public:
|
||||
// default constructor does nothing
|
||||
|
|
|
|||
|
|
@ -647,7 +647,7 @@ struct node_t
|
|||
|
||||
int firstface; // decision node only
|
||||
int numfaces; // decision node only
|
||||
twosided<std::unique_ptr<node_t>>
|
||||
twosided<node_t *>
|
||||
children; // children[0] = front side, children[1] = back side of plane. only valid for decision nodes
|
||||
std::list<std::unique_ptr<face_t>> facelist; // decision nodes only, list for both sides
|
||||
|
||||
|
|
|
|||
|
|
@ -29,21 +29,32 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
struct node_t;
|
||||
#include <tbb/concurrent_vector.h>
|
||||
|
||||
struct portal_t;
|
||||
|
||||
struct tree_t
|
||||
{
|
||||
std::unique_ptr<node_t> headnode;
|
||||
node_t *headnode;
|
||||
node_t outside_node = {}; // portals outside the world face this
|
||||
aabb3d bounds;
|
||||
|
||||
// here for ownership/memory management - not intended to be iterated directly
|
||||
std::vector<std::unique_ptr<portal_t>> portals;
|
||||
|
||||
// here for ownership/memory management - not intended to be iterated directly
|
||||
//
|
||||
// concurrent_vector allows BrushBSP to insert nodes in parallel, and also
|
||||
// promises not to move elements so we can omit the std::unique_ptr wrapper.
|
||||
tbb::concurrent_vector<node_t> nodes;
|
||||
|
||||
// creates a new portal owned by `this` (stored in the `portals` vector) and
|
||||
// returns a raw pointer to it
|
||||
portal_t *create_portal();
|
||||
|
||||
// creates a new node owned by `this` (stored in the `nodes` vector) and
|
||||
// returns a raw pointer to it
|
||||
node_t *create_node();
|
||||
};
|
||||
|
||||
void FreeTreePortals(tree_t *tree);
|
||||
|
|
|
|||
|
|
@ -75,7 +75,9 @@ if (embree_FOUND)
|
|||
|
||||
add_custom_command(TARGET light POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:embree>" "$<TARGET_FILE_DIR:light>"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:TBB::tbb>" "$<TARGET_FILE_DIR:light>")
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:TBB::tbb>" "$<TARGET_FILE_DIR:light>"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:TBB::tbbmalloc>" "$<TARGET_FILE_DIR:light>"
|
||||
)
|
||||
|
||||
if (NOT EMBREE_LICENSE STREQUAL EMBREE_LICENSE-NOTFOUND)
|
||||
add_custom_command(TARGET light POST_BUILD
|
||||
|
|
@ -103,9 +105,18 @@ if (embree_FOUND)
|
|||
message(STATUS "TBB .so file: ${TBB_SO_FILE}")
|
||||
|
||||
install(FILES ${TBB_SO_FILE} DESTINATION bin)
|
||||
|
||||
# tbbmalloc
|
||||
get_target_property(TBBMALLOC_SO_FILE_SYMLINK TBB::tbbmalloc IMPORTED_LOCATION_RELEASE)
|
||||
get_filename_component(TBBMALLOC_SO_FILE "${TBBMALLOC_SO_FILE_SYMLINK}" REALPATH)
|
||||
|
||||
message(STATUS "TBBMALLOC .so file: ${TBBMALLOC_SO_FILE}")
|
||||
|
||||
install(FILES ${TBBMALLOC_SO_FILE} DESTINATION bin)
|
||||
else()
|
||||
# preferred method
|
||||
install(FILES $<TARGET_FILE:TBB::tbb> DESTINATION bin)
|
||||
install(FILES $<TARGET_FILE:TBB::tbbmalloc> DESTINATION bin)
|
||||
endif()
|
||||
|
||||
if (NOT EMBREE_LICENSE STREQUAL EMBREE_LICENSE-NOTFOUND)
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ set(QBSP_SOURCES
|
|||
${QBSP_INCLUDES})
|
||||
|
||||
add_library(libqbsp STATIC ${QBSP_SOURCES})
|
||||
target_link_libraries(libqbsp common ${CMAKE_THREAD_LIBS_INIT} TBB::tbb fmt::fmt nlohmann_json::nlohmann_json pareto)
|
||||
target_link_libraries(libqbsp common ${CMAKE_THREAD_LIBS_INIT} TBB::tbb TBB::tbbmalloc fmt::fmt nlohmann_json::nlohmann_json pareto)
|
||||
|
||||
add_executable(qbsp main.cc)
|
||||
target_link_libraries(qbsp libqbsp)
|
||||
|
|
@ -40,4 +40,5 @@ install(TARGETS qbsp RUNTIME DESTINATION bin)
|
|||
|
||||
# HACK: copy .dll dependencies
|
||||
add_custom_command(TARGET qbsp POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:TBB::tbb>" "$<TARGET_FILE_DIR:qbsp>")
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:TBB::tbb>" "$<TARGET_FILE_DIR:qbsp>"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:TBB::tbbmalloc>" "$<TARGET_FILE_DIR:qbsp>")
|
||||
|
|
|
|||
|
|
@ -980,7 +980,7 @@ BuildTree_r
|
|||
Called in parallel.
|
||||
==================
|
||||
*/
|
||||
static void BuildTree_r(node_t *node, std::vector<std::unique_ptr<bspbrush_t>> brushes, std::optional<bool> forced_quick_tree, bspstats_t &stats)
|
||||
static void BuildTree_r(tree_t *tree, node_t *node, std::vector<std::unique_ptr<bspbrush_t>> brushes, std::optional<bool> forced_quick_tree, bspstats_t &stats)
|
||||
{
|
||||
// find the best plane to use as a splitter
|
||||
auto bestplane = SelectSplitPlane(brushes, node, forced_quick_tree, stats);
|
||||
|
|
@ -1008,7 +1008,7 @@ static void BuildTree_r(node_t *node, std::vector<std::unique_ptr<bspbrush_t>> b
|
|||
|
||||
// allocate children before recursing
|
||||
for (int i = 0; i < 2; i++) {
|
||||
auto &newnode = node->children[i] = std::make_unique<node_t>();
|
||||
auto &newnode = node->children[i] = tree->create_node();
|
||||
newnode->parent = node;
|
||||
newnode->bounds = node->bounds;
|
||||
}
|
||||
|
|
@ -1021,14 +1021,16 @@ static void BuildTree_r(node_t *node, std::vector<std::unique_ptr<bspbrush_t>> b
|
|||
}
|
||||
}
|
||||
|
||||
auto children_volumes = SplitBrush(node->volume->copy_unique(), bestplane.value(), stats);
|
||||
// to save time/memory we can destroy node's volume at this point
|
||||
auto children_volumes = SplitBrush(std::move(node->volume), bestplane.value(), stats);
|
||||
node->volume = nullptr;
|
||||
node->children[0]->volume = std::move(children_volumes[0]);
|
||||
node->children[1]->volume = std::move(children_volumes[1]);
|
||||
|
||||
// recursively process children
|
||||
tbb::task_group g;
|
||||
g.run([&]() { BuildTree_r(node->children[0].get(), std::move(children[0]), forced_quick_tree, stats); });
|
||||
g.run([&]() { BuildTree_r(node->children[1].get(), std::move(children[1]), forced_quick_tree, stats); });
|
||||
g.run([&]() { BuildTree_r(tree, node->children[0], std::move(children[0]), forced_quick_tree, stats); });
|
||||
g.run([&]() { BuildTree_r(tree, node->children[1], std::move(children[1]), forced_quick_tree, stats); });
|
||||
g.wait();
|
||||
}
|
||||
|
||||
|
|
@ -1079,22 +1081,22 @@ static std::unique_ptr<tree_t> BrushBSP_internal(mapentity_t *entity, std::vecto
|
|||
* collision hull for the engine. Probably could be done a little
|
||||
* smarter, but this works.
|
||||
*/
|
||||
auto headnode = std::make_unique<node_t>();
|
||||
auto headnode = tree->create_node();
|
||||
headnode->bounds = entity->bounds;
|
||||
// The choice of plane is mostly unimportant, but having it at (0, 0, 0) affects
|
||||
// the node bounds calculation.
|
||||
headnode->planenum = 0;
|
||||
headnode->children[0] = std::make_unique<node_t>();
|
||||
headnode->children[0] = tree->create_node();
|
||||
headnode->children[0]->is_leaf = true;
|
||||
headnode->children[0]->contents = qbsp_options.target_game->create_empty_contents();
|
||||
headnode->children[0]->parent = headnode.get();
|
||||
headnode->children[1] = std::make_unique<node_t>();
|
||||
headnode->children[0]->parent = headnode;
|
||||
headnode->children[1] = tree->create_node();
|
||||
headnode->children[1]->is_leaf = true;
|
||||
headnode->children[1]->contents = qbsp_options.target_game->create_empty_contents();
|
||||
headnode->children[1]->parent = headnode.get();
|
||||
headnode->children[1]->parent = headnode;
|
||||
|
||||
tree->bounds = headnode->bounds;
|
||||
tree->headnode = std::move(headnode);
|
||||
tree->headnode = headnode;
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
|
@ -1103,16 +1105,16 @@ static std::unique_ptr<tree_t> BrushBSP_internal(mapentity_t *entity, std::vecto
|
|||
logging::print(logging::flag::STAT, " {:8} visible faces\n", c_faces);
|
||||
logging::print(logging::flag::STAT, " {:8} nonvisible faces\n", c_nonvisfaces);
|
||||
|
||||
auto node = std::make_unique<node_t>();
|
||||
auto node = tree->create_node();
|
||||
|
||||
node->volume = BrushFromBounds(tree->bounds.grow(SIDESPACE));
|
||||
node->bounds = tree->bounds.grow(SIDESPACE);
|
||||
|
||||
tree->headnode = std::move(node);
|
||||
tree->headnode = node;
|
||||
|
||||
bspstats_t stats{};
|
||||
stats.leafstats = qbsp_options.target_game->create_content_stats();
|
||||
BuildTree_r(tree->headnode.get(), std::move(brushlist), forced_quick_tree, stats);
|
||||
BuildTree_r(tree.get(), tree->headnode, std::move(brushlist), forced_quick_tree, stats);
|
||||
|
||||
logging::print(logging::flag::STAT, " {:8} visible nodes\n", stats.c_nodes - stats.c_nonvis);
|
||||
if (stats.c_nonvis) {
|
||||
|
|
|
|||
|
|
@ -133,8 +133,8 @@ static void ExportObj_Nodes_r(const node_t *node, std::vector<const face_t *> *d
|
|||
dest->push_back(face.get());
|
||||
}
|
||||
|
||||
ExportObj_Nodes_r(node->children[0].get(), dest);
|
||||
ExportObj_Nodes_r(node->children[1].get(), dest);
|
||||
ExportObj_Nodes_r(node->children[0], dest);
|
||||
ExportObj_Nodes_r(node->children[1], dest);
|
||||
}
|
||||
|
||||
void ExportObj_Nodes(const std::string &filesuffix, const node_t *nodes)
|
||||
|
|
@ -147,8 +147,8 @@ void ExportObj_Nodes(const std::string &filesuffix, const node_t *nodes)
|
|||
static void ExportObj_Marksurfaces_r(const node_t *node, std::unordered_set<const face_t *> *dest)
|
||||
{
|
||||
if (!node->is_leaf) {
|
||||
ExportObj_Marksurfaces_r(node->children[0].get(), dest);
|
||||
ExportObj_Marksurfaces_r(node->children[1].get(), dest);
|
||||
ExportObj_Marksurfaces_r(node->children[0], dest);
|
||||
ExportObj_Marksurfaces_r(node->children[1], dest);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -101,8 +101,8 @@ static void EmitVertices_R(node_t *node)
|
|||
EmitFaceVertices(f.get());
|
||||
}
|
||||
|
||||
EmitVertices_R(node->children[0].get());
|
||||
EmitVertices_R(node->children[1].get());
|
||||
EmitVertices_R(node->children[0]);
|
||||
EmitVertices_R(node->children[1]);
|
||||
}
|
||||
|
||||
void EmitVertices(node_t *headnode)
|
||||
|
|
@ -184,8 +184,8 @@ static void MakeFaceEdges_r(node_t *node)
|
|||
FindFaceEdges(f.get());
|
||||
}
|
||||
|
||||
MakeFaceEdges_r(node->children[0].get());
|
||||
MakeFaceEdges_r(node->children[1].get());
|
||||
MakeFaceEdges_r(node->children[0]);
|
||||
MakeFaceEdges_r(node->children[1]);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -253,8 +253,8 @@ static void EmitFaceFragments_R(node_t *node)
|
|||
|
||||
node->numfaces = static_cast<int>(map.bsp.dfaces.size()) - node->firstface;
|
||||
|
||||
EmitFaceFragments_R(node->children[0].get());
|
||||
EmitFaceFragments_R(node->children[1].get());
|
||||
EmitFaceFragments_R(node->children[0]);
|
||||
EmitFaceFragments_R(node->children[1]);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -299,10 +299,10 @@ static void AddMarksurfaces_r(face_t *face, std::unique_ptr<face_t> face_copy, n
|
|||
|
||||
auto [frontFragment, backFragment] = SplitFace(std::move(face_copy), splitplane);
|
||||
if (frontFragment) {
|
||||
AddMarksurfaces_r(face, std::move(frontFragment), node->children[0].get());
|
||||
AddMarksurfaces_r(face, std::move(frontFragment), node->children[0]);
|
||||
}
|
||||
if (backFragment) {
|
||||
AddMarksurfaces_r(face, std::move(backFragment), node->children[1].get());
|
||||
AddMarksurfaces_r(face, std::move(backFragment), node->children[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -324,12 +324,12 @@ void MakeMarkFaces(node_t *node)
|
|||
// add this face to all descendant leafs it touches
|
||||
|
||||
// make a copy we can clip
|
||||
AddMarksurfaces_r(face.get(), CopyFace(face.get()), node->children[face->planenum & 1].get());
|
||||
AddMarksurfaces_r(face.get(), CopyFace(face.get()), node->children[face->planenum & 1]);
|
||||
}
|
||||
|
||||
// process child nodes recursively
|
||||
MakeMarkFaces(node->children[0].get());
|
||||
MakeMarkFaces(node->children[1].get());
|
||||
MakeMarkFaces(node->children[0]);
|
||||
MakeMarkFaces(node->children[1]);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -531,8 +531,8 @@ static void MakeFaces_r(node_t *node, makefaces_stats_t &stats)
|
|||
{
|
||||
// recurse down to leafs
|
||||
if (!node->is_leaf) {
|
||||
MakeFaces_r(node->children[0].get(), stats);
|
||||
MakeFaces_r(node->children[1].get(), stats);
|
||||
MakeFaces_r(node->children[0], stats);
|
||||
MakeFaces_r(node->children[1], stats);
|
||||
|
||||
// merge together all visible faces on the node
|
||||
if (!qbsp_options.nomerge.value())
|
||||
|
|
|
|||
|
|
@ -63,15 +63,15 @@ static node_t *PointInLeaf(node_t *node, const qvec3d &point)
|
|||
|
||||
if (dist > 0) {
|
||||
// point is on the front of the node plane
|
||||
return PointInLeaf(node->children[0].get(), point);
|
||||
return PointInLeaf(node->children[0], point);
|
||||
} else if (dist < 0) {
|
||||
// point is on the back of the node plane
|
||||
return PointInLeaf(node->children[1].get(), point);
|
||||
return PointInLeaf(node->children[1], point);
|
||||
} else {
|
||||
// point is exactly on the node plane
|
||||
|
||||
node_t *front = PointInLeaf(node->children[0].get(), point);
|
||||
node_t *back = PointInLeaf(node->children[1].get(), point);
|
||||
node_t *front = PointInLeaf(node->children[0], point);
|
||||
node_t *back = PointInLeaf(node->children[1], point);
|
||||
|
||||
// prefer the opaque one
|
||||
if (LeafSealsMap(front)) {
|
||||
|
|
@ -89,8 +89,8 @@ static void ClearOccupied_r(node_t *node)
|
|||
node->occupant = nullptr;
|
||||
|
||||
if (!node->is_leaf) {
|
||||
ClearOccupied_r(node->children[0].get());
|
||||
ClearOccupied_r(node->children[1].get());
|
||||
ClearOccupied_r(node->children[0]);
|
||||
ClearOccupied_r(node->children[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -117,8 +117,8 @@ static void MarkClusterOutsideDistance_R(node_t *node, int outside_distance)
|
|||
node->outside_distance = outside_distance;
|
||||
|
||||
if (!node->is_leaf) {
|
||||
MarkClusterOutsideDistance_R(node->children[0].get(), outside_distance);
|
||||
MarkClusterOutsideDistance_R(node->children[1].get(), outside_distance);
|
||||
MarkClusterOutsideDistance_R(node->children[0], outside_distance);
|
||||
MarkClusterOutsideDistance_R(node->children[1], outside_distance);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -328,8 +328,8 @@ static void FindOccupiedClusters_R(node_t *node, std::vector<node_t *> &result)
|
|||
}
|
||||
|
||||
if (!node->is_leaf) {
|
||||
FindOccupiedClusters_R(node->children[0].get(), result);
|
||||
FindOccupiedClusters_R(node->children[1].get(), result);
|
||||
FindOccupiedClusters_R(node->children[0], result);
|
||||
FindOccupiedClusters_R(node->children[1], result);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -363,8 +363,8 @@ static void MarkAllBrushSidesVisible_R(node_t *node)
|
|||
{
|
||||
// descend to leafs
|
||||
if (!node->is_leaf) {
|
||||
MarkAllBrushSidesVisible_R(node->children[0].get());
|
||||
MarkAllBrushSidesVisible_R(node->children[1].get());
|
||||
MarkAllBrushSidesVisible_R(node->children[0]);
|
||||
MarkAllBrushSidesVisible_R(node->children[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -387,8 +387,8 @@ static void MarkVisibleBrushSides_R(node_t *node)
|
|||
{
|
||||
// descent to leafs
|
||||
if (!node->is_leaf) {
|
||||
MarkVisibleBrushSides_R(node->children[0].get());
|
||||
MarkVisibleBrushSides_R(node->children[1].get());
|
||||
MarkVisibleBrushSides_R(node->children[0]);
|
||||
MarkVisibleBrushSides_R(node->children[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -432,8 +432,8 @@ static void MarkVisibleBrushSides_R(node_t *node)
|
|||
static void OutLeafsToSolid_r(node_t *node, int *outleafs_count, settings::filltype_t filltype)
|
||||
{
|
||||
if (!node->is_leaf) {
|
||||
OutLeafsToSolid_r(node->children[0].get(), outleafs_count, filltype);
|
||||
OutLeafsToSolid_r(node->children[1].get(), outleafs_count, filltype);
|
||||
OutLeafsToSolid_r(node->children[0], outleafs_count, filltype);
|
||||
OutLeafsToSolid_r(node->children[1], outleafs_count, filltype);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -471,8 +471,8 @@ static int OutLeafsToSolid(node_t *node, settings::filltype_t filltype)
|
|||
static void SetOccupied_R(node_t *node, int dist)
|
||||
{
|
||||
if (!node->is_leaf) {
|
||||
SetOccupied_R(node->children[0].get(), dist);
|
||||
SetOccupied_R(node->children[1].get(), dist);
|
||||
SetOccupied_R(node->children[0], dist);
|
||||
SetOccupied_R(node->children[1], dist);
|
||||
}
|
||||
|
||||
node->occupied = dist;
|
||||
|
|
@ -601,7 +601,7 @@ Special cases: structural fully covered by detail still needs to be marked "visi
|
|||
*/
|
||||
bool FillOutside(mapentity_t *entity, tree_t *tree, const int hullnum, bspbrush_vector_t &brushes)
|
||||
{
|
||||
node_t *node = tree->headnode.get();
|
||||
node_t *node = tree->headnode;
|
||||
|
||||
logging::funcheader();
|
||||
|
||||
|
|
@ -724,9 +724,9 @@ void FillBrushEntity(mapentity_t *entity, tree_t *tree, const int hullnum, bspbr
|
|||
logging::funcheader();
|
||||
|
||||
// Clear the outside filling state on all nodes
|
||||
ClearOccupied_r(tree->headnode.get());
|
||||
ClearOccupied_r(tree->headnode);
|
||||
|
||||
MarkBrushSidesInvisible(entity, brushes);
|
||||
|
||||
MarkVisibleBrushSides_R(tree->headnode.get());
|
||||
MarkVisibleBrushSides_R(tree->headnode);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ contentflags_t ClusterContents(const node_t *node)
|
|||
return node->contents;
|
||||
|
||||
return qbsp_options.target_game->cluster_contents(
|
||||
ClusterContents(node->children[0].get()), ClusterContents(node->children[1].get()));
|
||||
ClusterContents(node->children[0]), ClusterContents(node->children[1]));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -160,9 +160,9 @@ std::list<std::unique_ptr<buildportal_t>> MakeHeadnodePortals(tree_t *tree)
|
|||
|
||||
p->winding = std::make_unique<winding_t>(BaseWindingForPlane(pl));
|
||||
if (side) {
|
||||
p->set_nodes(&tree->outside_node, tree->headnode.get());
|
||||
p->set_nodes(&tree->outside_node, tree->headnode);
|
||||
} else {
|
||||
p->set_nodes(tree->headnode.get(), &tree->outside_node);
|
||||
p->set_nodes(tree->headnode, &tree->outside_node);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -209,7 +209,7 @@ static std::optional<winding_t> BaseWindingForNode(const node_t *node)
|
|||
// clip by all the parents
|
||||
for (auto *np = node->parent; np && w;) {
|
||||
|
||||
if (np->children[0].get() == node) {
|
||||
if (np->children[0] == node) {
|
||||
w = w->clip_front(np->get_plane(), BASE_WINDING_EPSILON, false);
|
||||
} else {
|
||||
w = w->clip_back(np->get_plane(), BASE_WINDING_EPSILON, false);
|
||||
|
|
@ -267,7 +267,7 @@ std::unique_ptr<buildportal_t> MakeNodePortal(node_t *node, const std::list<std:
|
|||
new_portal->plane = node->get_plane();
|
||||
new_portal->onnode = node;
|
||||
new_portal->winding = std::make_unique<winding_t>(*w);
|
||||
new_portal->set_nodes(node->children[0].get(), node->children[1].get());
|
||||
new_portal->set_nodes(node->children[0], node->children[1]);
|
||||
|
||||
return new_portal;
|
||||
}
|
||||
|
|
@ -283,8 +283,8 @@ children have portals instead of node.
|
|||
twosided<std::list<std::unique_ptr<buildportal_t>>> SplitNodePortals(const node_t *node, std::list<std::unique_ptr<buildportal_t>> boundary_portals, portalstats_t &stats)
|
||||
{
|
||||
const auto &plane = node->get_plane();
|
||||
node_t *f = node->children[0].get();
|
||||
node_t *b = node->children[1].get();
|
||||
node_t *f = node->children[0];
|
||||
node_t *b = node->children[1];
|
||||
|
||||
twosided<std::list<std::unique_ptr<buildportal_t>>> result;
|
||||
|
||||
|
|
@ -405,8 +405,8 @@ static void CalcTreeBounds_r(tree_t *tree, node_t *node)
|
|||
CalcNodeBounds(node);
|
||||
} else {
|
||||
tbb::task_group g;
|
||||
g.run([&]() { CalcTreeBounds_r(tree, node->children[0].get()); });
|
||||
g.run([&]() { CalcTreeBounds_r(tree, node->children[1].get()); });
|
||||
g.run([&]() { CalcTreeBounds_r(tree, node->children[0]); });
|
||||
g.run([&]() { CalcTreeBounds_r(tree, node->children[1]); });
|
||||
g.wait();
|
||||
|
||||
node->bounds = node->children[0]->bounds + node->children[1]->bounds;
|
||||
|
|
@ -449,8 +449,8 @@ static std::list<std::unique_ptr<buildportal_t>> ClipNodePortalsToTree_r(node_t
|
|||
|
||||
auto boundary_portals_split = SplitNodePortals(node, std::move(portals), stats);
|
||||
|
||||
auto front_fragments = ClipNodePortalsToTree_r(node->children[0].get(), type, std::move(boundary_portals_split.front), stats);
|
||||
auto back_fragments = ClipNodePortalsToTree_r(node->children[1].get(), type, std::move(boundary_portals_split.back), stats);
|
||||
auto front_fragments = ClipNodePortalsToTree_r(node->children[0], type, std::move(boundary_portals_split.front), stats);
|
||||
auto back_fragments = ClipNodePortalsToTree_r(node->children[1], type, std::move(boundary_portals_split.back), stats);
|
||||
|
||||
std::list<std::unique_ptr<buildportal_t>> merged_result;
|
||||
merged_result.splice(merged_result.end(), front_fragments);
|
||||
|
|
@ -482,8 +482,8 @@ std::list<std::unique_ptr<buildportal_t>> MakeTreePortals_r(tree_t *tree, node_t
|
|||
std::list<std::unique_ptr<buildportal_t>> result_portals_front, result_portals_back;
|
||||
|
||||
tbb::task_group g;
|
||||
g.run([&]() { result_portals_front = MakeTreePortals_r(tree, node->children[0].get(), type, std::move(boundary_portals_split.front), stats); });
|
||||
g.run([&]() { result_portals_back = MakeTreePortals_r(tree, node->children[1].get(), type, std::move(boundary_portals_split.back), stats); });
|
||||
g.run([&]() { result_portals_front = MakeTreePortals_r(tree, node->children[0], type, std::move(boundary_portals_split.front), stats); });
|
||||
g.run([&]() { result_portals_back = MakeTreePortals_r(tree, node->children[1], type, std::move(boundary_portals_split.back), stats); });
|
||||
g.wait();
|
||||
|
||||
// sequential part: push the nodeportal down each side of the bsp so it connects leafs
|
||||
|
|
@ -495,9 +495,9 @@ std::list<std::unique_ptr<buildportal_t>> MakeTreePortals_r(tree_t *tree, node_t
|
|||
// these portal fragments have node->children[1] on one side, and the leaf nodes from
|
||||
// node->children[0] on the other side
|
||||
std::list<std::unique_ptr<buildportal_t>> half_clipped =
|
||||
ClipNodePortalsToTree_r(node->children[0].get(), type, make_list(std::move(nodeportal)), stats);
|
||||
ClipNodePortalsToTree_r(node->children[0], type, make_list(std::move(nodeportal)), stats);
|
||||
|
||||
for (auto &clipped_p : ClipNodePortalsToTree_r(node->children[1].get(), type, std::move(half_clipped), stats)) {
|
||||
for (auto &clipped_p : ClipNodePortalsToTree_r(node->children[1], type, std::move(half_clipped), stats)) {
|
||||
result_portals_onnode.push_back(std::move(clipped_p));
|
||||
}
|
||||
}
|
||||
|
|
@ -527,13 +527,13 @@ void MakeTreePortals(tree_t *tree)
|
|||
|
||||
auto headnodeportals = MakeHeadnodePortals(tree);
|
||||
|
||||
auto buildportals = MakeTreePortals_r(tree, tree->headnode.get(), portaltype_t::TREE, std::move(headnodeportals), stats);
|
||||
auto buildportals = MakeTreePortals_r(tree, tree->headnode, portaltype_t::TREE, std::move(headnodeportals), stats);
|
||||
|
||||
MakePortalsFromBuildportals(tree, std::move(buildportals));
|
||||
|
||||
logging::header("CalcTreeBounds");
|
||||
|
||||
CalcTreeBounds_r(tree, tree->headnode.get());
|
||||
CalcTreeBounds_r(tree, tree->headnode);
|
||||
|
||||
logging::print(logging::flag::STAT, " {:8} tiny portals\n", stats.c_tinyportals);
|
||||
logging::print(logging::flag::STAT, " {:8} tree portals\n", tree->portals.size());
|
||||
|
|
@ -544,14 +544,14 @@ static void AssertNoPortals_r(node_t *node)
|
|||
Q_assert(!node->portals);
|
||||
|
||||
if (!node->is_leaf) {
|
||||
AssertNoPortals_r(node->children[0].get());
|
||||
AssertNoPortals_r(node->children[1].get());
|
||||
AssertNoPortals_r(node->children[0]);
|
||||
AssertNoPortals_r(node->children[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void AssertNoPortals(tree_t *tree)
|
||||
{
|
||||
AssertNoPortals_r(tree->headnode.get());
|
||||
AssertNoPortals_r(tree->headnode);
|
||||
Q_assert(!tree->outside_node.portals);
|
||||
Q_assert(tree->portals.empty());
|
||||
}
|
||||
|
|
@ -569,8 +569,8 @@ static void ApplyArea_r(node_t *node)
|
|||
node->area = map.c_areas;
|
||||
|
||||
if (!node->is_leaf) {
|
||||
ApplyArea_r(node->children[0].get());
|
||||
ApplyArea_r(node->children[1].get());
|
||||
ApplyArea_r(node->children[0]);
|
||||
ApplyArea_r(node->children[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -578,10 +578,10 @@ static mapentity_t *AreanodeEntityForLeaf(node_t *node)
|
|||
{
|
||||
// if detail cluster, search the children recursively
|
||||
if (!node->is_leaf) {
|
||||
if (auto *child0result = AreanodeEntityForLeaf(node->children[0].get()); child0result) {
|
||||
if (auto *child0result = AreanodeEntityForLeaf(node->children[0]); child0result) {
|
||||
return child0result;
|
||||
}
|
||||
return AreanodeEntityForLeaf(node->children[1].get());
|
||||
return AreanodeEntityForLeaf(node->children[1]);
|
||||
}
|
||||
|
||||
for (auto &brush : node->original_brushes) {
|
||||
|
|
@ -691,8 +691,8 @@ area set, flood fill out from there
|
|||
static void SetAreaPortalAreas_r(node_t *node)
|
||||
{
|
||||
if (!node->is_leaf) {
|
||||
SetAreaPortalAreas_r(node->children[0].get());
|
||||
SetAreaPortalAreas_r(node->children[1].get());
|
||||
SetAreaPortalAreas_r(node->children[0]);
|
||||
SetAreaPortalAreas_r(node->children[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -895,8 +895,8 @@ MarkVisibleSides_r
|
|||
static void MarkVisibleSides_r(node_t *node)
|
||||
{
|
||||
if (!node->is_leaf) {
|
||||
MarkVisibleSides_r(node->children[0].get());
|
||||
MarkVisibleSides_r(node->children[1].get());
|
||||
MarkVisibleSides_r(node->children[0]);
|
||||
MarkVisibleSides_r(node->children[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -938,5 +938,5 @@ void MarkVisibleSides(tree_t *tree, mapentity_t *entity, bspbrush_vector_t &brus
|
|||
}
|
||||
|
||||
// set visible flags on the sides that are used by portals
|
||||
MarkVisibleSides_r(tree->headnode.get());
|
||||
MarkVisibleSides_r(tree->headnode);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,8 +55,8 @@ static void WritePortals_r(node_t *node, std::ofstream &portalFile, bool cluster
|
|||
qplane3d plane2;
|
||||
|
||||
if (!node->is_leaf && !node->detail_separator) {
|
||||
WritePortals_r(node->children[0].get(), portalFile, clusters);
|
||||
WritePortals_r(node->children[1].get(), portalFile, clusters);
|
||||
WritePortals_r(node->children[0], portalFile, clusters);
|
||||
WritePortals_r(node->children[1], portalFile, clusters);
|
||||
return;
|
||||
}
|
||||
if (node->contents.is_solid(qbsp_options.target_game))
|
||||
|
|
@ -102,8 +102,8 @@ static void WritePortals_r(node_t *node, std::ofstream &portalFile, bool cluster
|
|||
static int WriteClusters_r(node_t *node, std::ofstream &portalFile, int viscluster)
|
||||
{
|
||||
if (!node->is_leaf) {
|
||||
viscluster = WriteClusters_r(node->children[0].get(), portalFile, viscluster);
|
||||
viscluster = WriteClusters_r(node->children[1].get(), portalFile, viscluster);
|
||||
viscluster = WriteClusters_r(node->children[0], portalFile, viscluster);
|
||||
viscluster = WriteClusters_r(node->children[1], portalFile, viscluster);
|
||||
return viscluster;
|
||||
}
|
||||
if (node->contents.is_solid(qbsp_options.target_game))
|
||||
|
|
@ -168,8 +168,8 @@ static void NumberLeafs_r(node_t *node, portal_state_t *state, int cluster)
|
|||
node->viscluster = cluster;
|
||||
CountPortals(node, state);
|
||||
}
|
||||
NumberLeafs_r(node->children[0].get(), state, cluster);
|
||||
NumberLeafs_r(node->children[1].get(), state, cluster);
|
||||
NumberLeafs_r(node->children[0], state, cluster);
|
||||
NumberLeafs_r(node->children[1], state, cluster);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -270,12 +270,12 @@ void WritePortalFile(tree_t *tree)
|
|||
portalstats_t stats{};
|
||||
|
||||
// vis portal generation doesn't use headnode portals
|
||||
auto buildportals = MakeTreePortals_r(tree, tree->headnode.get(), portaltype_t::VIS, {}, stats);
|
||||
auto buildportals = MakeTreePortals_r(tree, tree->headnode, portaltype_t::VIS, {}, stats);
|
||||
|
||||
MakePortalsFromBuildportals(tree, std::move(buildportals));
|
||||
|
||||
/* save portal file for vis tracing */
|
||||
WritePortalfile(tree->headnode.get(), &state);
|
||||
WritePortalfile(tree->headnode, &state);
|
||||
|
||||
logging::print(logging::flag::STAT, " {:8} vis leafs\n", state.num_visleafs);
|
||||
logging::print(logging::flag::STAT, " {:8} vis clusters\n", state.num_visclusters);
|
||||
|
|
|
|||
38
qbsp/qbsp.cc
38
qbsp/qbsp.cc
|
|
@ -331,8 +331,8 @@ static void ExportBrushList_r(const mapentity_t *entity, node_t *node)
|
|||
return;
|
||||
}
|
||||
|
||||
ExportBrushList_r(entity, node->children[0].get());
|
||||
ExportBrushList_r(entity, node->children[1].get());
|
||||
ExportBrushList_r(entity, node->children[0]);
|
||||
ExportBrushList_r(entity, node->children[1]);
|
||||
}
|
||||
|
||||
static void ExportBrushList(mapentity_t *entity, node_t *node)
|
||||
|
|
@ -376,8 +376,8 @@ static void CountLeafs_r(node_t *node, content_stats_base_t &stats)
|
|||
qbsp_options.target_game->count_contents_in_stats(node->contents, stats);
|
||||
return;
|
||||
}
|
||||
CountLeafs_r(node->children[0].get(), stats);
|
||||
CountLeafs_r(node->children[1].get(), stats);
|
||||
CountLeafs_r(node->children[0], stats);
|
||||
CountLeafs_r(node->children[1], stats);
|
||||
}
|
||||
|
||||
static void CountLeafs(node_t *headnode)
|
||||
|
|
@ -486,10 +486,10 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum)
|
|||
// fill again so PruneNodes works
|
||||
MakeTreePortals(tree.get());
|
||||
FillOutside(entity, tree.get(), hullnum, brushes);
|
||||
PruneNodes(tree->headnode.get());
|
||||
PruneNodes(tree->headnode);
|
||||
}
|
||||
}
|
||||
ExportClipNodes(entity, tree->headnode.get(), hullnum);
|
||||
ExportClipNodes(entity, tree->headnode, hullnum);
|
||||
|
||||
// fixme-brushbsp: return here?
|
||||
} else {
|
||||
|
|
@ -521,8 +521,8 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum)
|
|||
|
||||
// Area portals
|
||||
if (qbsp_options.target_game->id == GAME_QUAKE_II) {
|
||||
FloodAreas(entity, tree->headnode.get());
|
||||
EmitAreaPortals(tree->headnode.get());
|
||||
FloodAreas(entity, tree->headnode);
|
||||
EmitAreaPortals(tree->headnode);
|
||||
}
|
||||
} else {
|
||||
FillBrushEntity(entity, tree.get(), hullnum, brushes);
|
||||
|
|
@ -534,39 +534,39 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum)
|
|||
MakeTreePortals(tree.get());
|
||||
|
||||
MarkVisibleSides(tree.get(), entity, brushes);
|
||||
MakeFaces(tree->headnode.get());
|
||||
MakeFaces(tree->headnode);
|
||||
|
||||
FreeTreePortals(tree.get());
|
||||
PruneNodes(tree->headnode.get());
|
||||
PruneNodes(tree->headnode);
|
||||
|
||||
if (hullnum <= 0 && entity == map.world_entity() && (!map.leakfile || qbsp_options.keepprt.value())) {
|
||||
WritePortalFile(tree.get());
|
||||
}
|
||||
|
||||
// needs to come after any face creation
|
||||
MakeMarkFaces(tree->headnode.get());
|
||||
MakeMarkFaces(tree->headnode);
|
||||
|
||||
CountLeafs(tree->headnode.get());
|
||||
CountLeafs(tree->headnode);
|
||||
|
||||
// output vertices first, since TJunc needs it
|
||||
EmitVertices(tree->headnode.get());
|
||||
EmitVertices(tree->headnode);
|
||||
|
||||
TJunc(tree->headnode.get());
|
||||
TJunc(tree->headnode);
|
||||
|
||||
if (qbsp_options.objexport.value() && entity == map.world_entity()) {
|
||||
ExportObj_Nodes("pre_makefaceedges_plane_faces", tree->headnode.get());
|
||||
ExportObj_Marksurfaces("pre_makefaceedges_marksurfaces", tree->headnode.get());
|
||||
ExportObj_Nodes("pre_makefaceedges_plane_faces", tree->headnode);
|
||||
ExportObj_Marksurfaces("pre_makefaceedges_marksurfaces", tree->headnode);
|
||||
}
|
||||
|
||||
Q_assert(entity->firstoutputfacenumber == -1);
|
||||
|
||||
entity->firstoutputfacenumber = MakeFaceEdges(tree->headnode.get());
|
||||
entity->firstoutputfacenumber = MakeFaceEdges(tree->headnode);
|
||||
|
||||
if (qbsp_options.target_game->id == GAME_QUAKE_II) {
|
||||
ExportBrushList(entity, tree->headnode.get());
|
||||
ExportBrushList(entity, tree->headnode);
|
||||
}
|
||||
|
||||
ExportDrawNodes(entity, tree->headnode.get(), entity->firstoutputfacenumber);
|
||||
ExportDrawNodes(entity, tree->headnode, entity->firstoutputfacenumber);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -161,8 +161,8 @@ static void FindEdgeVerts_FaceBounds_R(const node_t *node, const aabb3d &aabb, s
|
|||
}
|
||||
}
|
||||
|
||||
FindEdgeVerts_FaceBounds_R(node->children[0].get(), aabb, verts);
|
||||
FindEdgeVerts_FaceBounds_R(node->children[1].get(), aabb, verts);
|
||||
FindEdgeVerts_FaceBounds_R(node->children[0], aabb, verts);
|
||||
FindEdgeVerts_FaceBounds_R(node->children[1], aabb, verts);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -845,8 +845,8 @@ static void FindFaces_r(node_t *node, std::unordered_set<face_t *> &faces)
|
|||
}
|
||||
}
|
||||
|
||||
FindFaces_r(node->children[0].get(), faces);
|
||||
FindFaces_r(node->children[1].get(), faces);
|
||||
FindFaces_r(node->children[0], faces);
|
||||
FindFaces_r(node->children[1], faces);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
17
qbsp/tree.cc
17
qbsp/tree.cc
|
|
@ -36,6 +36,13 @@ portal_t *tree_t::create_portal()
|
|||
return portals.emplace_back(std::make_unique<portal_t>()).get();
|
||||
}
|
||||
|
||||
node_t *tree_t::create_node()
|
||||
{
|
||||
auto it = nodes.grow_by(1);
|
||||
|
||||
return &(*it);
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
FreeTreePortals_r
|
||||
|
|
@ -45,8 +52,8 @@ FreeTreePortals_r
|
|||
static void ClearNodePortals_r(node_t *node)
|
||||
{
|
||||
if (!node->is_leaf) {
|
||||
ClearNodePortals_r(node->children[0].get());
|
||||
ClearNodePortals_r(node->children[1].get());
|
||||
ClearNodePortals_r(node->children[0]);
|
||||
ClearNodePortals_r(node->children[1]);
|
||||
}
|
||||
|
||||
node->portals = nullptr;
|
||||
|
|
@ -56,7 +63,7 @@ static void ClearNodePortals_r(node_t *node)
|
|||
|
||||
void FreeTreePortals(tree_t *tree)
|
||||
{
|
||||
ClearNodePortals_r(tree->headnode.get());
|
||||
ClearNodePortals_r(tree->headnode);
|
||||
tree->outside_node.portals = nullptr;
|
||||
|
||||
tbb::parallel_for_each(tree->portals, [](std::unique_ptr<portal_t> &portal) {
|
||||
|
|
@ -97,8 +104,8 @@ static void PruneNodes_R(node_t *node, std::atomic<int32_t> &count_pruned)
|
|||
}
|
||||
|
||||
tbb::task_group g;
|
||||
g.run([&]() { PruneNodes_R(node->children[0].get(), count_pruned); });
|
||||
g.run([&]() { PruneNodes_R(node->children[1].get(), count_pruned); });
|
||||
g.run([&]() { PruneNodes_R(node->children[0], count_pruned); });
|
||||
g.run([&]() { PruneNodes_R(node->children[1], count_pruned); });
|
||||
g.wait();
|
||||
|
||||
if (node->children[0]->is_leaf && node->children[0]->contents.is_any_solid(qbsp_options.target_game) &&
|
||||
|
|
|
|||
|
|
@ -103,8 +103,8 @@ static size_t ExportClipNodes(node_t *node)
|
|||
const size_t nodenum = map.bsp.dclipnodes.size();
|
||||
map.bsp.dclipnodes.emplace_back();
|
||||
|
||||
const int child0 = ExportClipNodes(node->children[0].get());
|
||||
const int child1 = ExportClipNodes(node->children[1].get());
|
||||
const int child0 = ExportClipNodes(node->children[0]);
|
||||
const int child1 = ExportClipNodes(node->children[1]);
|
||||
|
||||
// Careful not to modify the vector while using this clipnode pointer
|
||||
bsp2_dclipnode_t &clipnode = map.bsp.dclipnodes[nodenum];
|
||||
|
|
@ -219,12 +219,12 @@ static void ExportDrawNodes(node_t *node)
|
|||
int32_t nextLeafIndex = static_cast<int32_t>(map.bsp.dleafs.size());
|
||||
const int32_t childnum = -(nextLeafIndex + 1);
|
||||
dnode->children[i] = childnum;
|
||||
ExportLeaf(node->children[i].get());
|
||||
ExportLeaf(node->children[i]);
|
||||
}
|
||||
} else {
|
||||
const int32_t childnum = static_cast<int32_t>(map.bsp.dnodes.size());
|
||||
dnode->children[i] = childnum;
|
||||
ExportDrawNodes(node->children[i].get());
|
||||
ExportDrawNodes(node->children[i]);
|
||||
|
||||
// Important: our dnode pointer may be invalid after the recursive call, if the vector got resized.
|
||||
// So re-set the pointer.
|
||||
|
|
|
|||
|
|
@ -23,12 +23,14 @@ if (NOT EMBREE_TBB_DLL STREQUAL EMBREE_TBB_DLL-NOTFOUND)
|
|||
message(STATUS "Found embree EMBREE_TBB_DLL: ${EMBREE_TBB_DLL}")
|
||||
endif()
|
||||
|
||||
target_link_libraries(tests libqbsp liblight libvis common TBB::tbb Catch2::Catch2WithMain fmt::fmt nanobench::nanobench)
|
||||
target_link_libraries(tests libqbsp liblight libvis common TBB::tbb TBB::tbbmalloc Catch2::Catch2WithMain fmt::fmt nanobench::nanobench)
|
||||
|
||||
# HACK: copy .dll dependencies
|
||||
add_custom_command(TARGET tests POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:embree>" "$<TARGET_FILE_DIR:tests>"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:TBB::tbb>" "$<TARGET_FILE_DIR:tests>")
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:TBB::tbb>" "$<TARGET_FILE_DIR:tests>"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:TBB::tbbmalloc>" "$<TARGET_FILE_DIR:tests>"
|
||||
)
|
||||
if (NOT EMBREE_TBB_DLL STREQUAL EMBREE_TBB_DLL-NOTFOUND)
|
||||
add_custom_command(TARGET tests POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${EMBREE_TBB_DLL}" "$<TARGET_FILE_DIR:tests>")
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ target_link_libraries(vis PRIVATE common libvis)
|
|||
|
||||
# HACK: copy .dll dependencies
|
||||
add_custom_command(TARGET vis POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:TBB::tbb>" "$<TARGET_FILE_DIR:vis>")
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:TBB::tbb>" "$<TARGET_FILE_DIR:vis>"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:TBB::tbbmalloc>" "$<TARGET_FILE_DIR:vis>"
|
||||
)
|
||||
|
||||
install(TARGETS vis RUNTIME DESTINATION bin)
|
||||
|
|
|
|||
Loading…
Reference in New Issue