Skip to content

Commit

Permalink
navigation mesh generation WIP
Browse files Browse the repository at this point in the history
Ideas tried and failed:
- Using the Recast navigation library. Can't stop it from shrinking the mesh away from ledges, while still keeping it away from walls. This means narrow platforms are excluded. Invisible floors would also be missing.
- Generating from the floors of CONTENTS_EMPTY leaves. This works well for indoor areas but has polys extending past ledges. Using the intersection of empty and solid leaves had similar problems.

What's working now:
Generating the clipnodes for a hull as normal, but then cutting out all of the faces that face into the void. Many faces have to be cut. A lot of them start out inside the level then extend out into infinity outside the level. By cutting faces against each other there is a clear separation of inside and outside faces. To test if a face is facing inside the level, the contents of the BSP is checked for every point above the face (super slow). The spacing of this grid of checks has to be small or else tiny faces are excluded.

Currently the entire clipnode hull is being rendered as the mesh, and it replaces the usual hull 3 render for the world. Stripping faces that players can't walk on will make it look like a normal nav mesh.
  • Loading branch information
wootguy committed Oct 20, 2023
1 parent 63086b3 commit 3dd3556
Show file tree
Hide file tree
Showing 17 changed files with 971 additions and 28 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ msvc
/release
/imgui
/qhull
/imgui_177
/imgui_178
/merge
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ set(SOURCE_FILES
src/util/util.h src/util/util.cpp
src/util/vectors.h src/util/vectors.cpp
src/util/mat4x4.h src/util/mat4x4.cpp
src/util/Polygon3D.h src/util/Polygon3D.cpp

# OpenGL rendering
src/gl/shaders.h src/gl/shaders.cpp
Expand Down Expand Up @@ -160,10 +161,12 @@ if(MSVC)

source_group("Header Files\\util" FILES src/util/util.h
src/util/vectors.h
src/util/Polygon3D.h
src/util/mat4x4.h)

source_group("Source Files\\util" FILES src/util/util.cpp
src/util/vectors.cpp
src/util/Polygon3D.cpp
src/util/mat4x4.cpp)

source_group("Header Files\\util\\lib" FILES src/util/lodepng.h)
Expand Down
12 changes: 6 additions & 6 deletions src/bsp/Bsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ void Bsp::getNodePlanes(int iNode, vector<int>& nodePlanes) {
}
}

vector<NodeVolumeCuts> Bsp::get_model_leaf_volume_cuts(int modelIdx, int hullIdx) {
vector<NodeVolumeCuts> Bsp::get_model_leaf_volume_cuts(int modelIdx, int hullIdx, int16_t contents) {
vector<NodeVolumeCuts> modelVolumeCuts;

if (hullIdx >= 0 && hullIdx < MAX_MAP_HULLS)
Expand All @@ -271,14 +271,14 @@ vector<NodeVolumeCuts> Bsp::get_model_leaf_volume_cuts(int modelIdx, int hullIdx
get_node_leaf_cuts(nodeIdx, clipOrder, modelVolumeCuts);
}
else {
get_clipnode_leaf_cuts(nodeIdx, clipOrder, modelVolumeCuts);
get_clipnode_leaf_cuts(nodeIdx, clipOrder, modelVolumeCuts, contents);
}
}
}
return modelVolumeCuts;
}

void Bsp::get_clipnode_leaf_cuts(int iNode, vector<BSPPLANE>& clipOrder, vector<NodeVolumeCuts>& output) {
void Bsp::get_clipnode_leaf_cuts(int iNode, vector<BSPPLANE>& clipOrder, vector<NodeVolumeCuts>& output, int16_t contents) {
BSPCLIPNODE& node = clipnodes[iNode];

if (node.iPlane < 0) {
Expand All @@ -294,9 +294,9 @@ void Bsp::get_clipnode_leaf_cuts(int iNode, vector<BSPPLANE>& clipOrder, vector<
clipOrder.push_back(plane);

if (node.iChildren[i] >= 0) {
get_clipnode_leaf_cuts(node.iChildren[i], clipOrder, output);
get_clipnode_leaf_cuts(node.iChildren[i], clipOrder, output, contents);
}
else if (node.iChildren[i] != CONTENTS_EMPTY) {
else if (node.iChildren[i] == contents) {
NodeVolumeCuts nodeVolumeCuts;
nodeVolumeCuts.nodeIdx = iNode;

Expand Down Expand Up @@ -327,7 +327,7 @@ void Bsp::get_node_leaf_cuts(int iNode, vector<BSPPLANE>& clipOrder, vector<Node
if (node.iChildren[i] >= 0) {
get_node_leaf_cuts(node.iChildren[i], clipOrder, output);
}
else if (leaves[~node.iChildren[i]].nContents != CONTENTS_EMPTY) {
else if (leaves[~node.iChildren[i]].nContents != CONTENTS_SOLID) {
NodeVolumeCuts nodeVolumeCuts;
nodeVolumeCuts.nodeIdx = iNode;

Expand Down
10 changes: 8 additions & 2 deletions src/bsp/Bsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
#include <set>
#include "bsptypes.h"

// largest coordinate allowed in map
//#define MAX_COORD 131072
#define MAX_COORD 32768

struct membuf : std::streambuf
{
membuf(char* begin, int len) {
Expand Down Expand Up @@ -107,8 +111,8 @@ class Bsp
bool is_node_hull_convex(int iNode);

// get cuts required to create bounding volumes for each solid leaf in the model
vector<NodeVolumeCuts> get_model_leaf_volume_cuts(int modelIdx, int hullIdx);
void get_clipnode_leaf_cuts(int iNode, vector<BSPPLANE>& clipOrder, vector<NodeVolumeCuts>& output);
vector<NodeVolumeCuts> get_model_leaf_volume_cuts(int modelIdx, int hullIdx, int16_t contents);
void get_clipnode_leaf_cuts(int iNode, vector<BSPPLANE>& clipOrder, vector<NodeVolumeCuts>& output, int16_t contents);
void get_node_leaf_cuts(int iNode, vector<BSPPLANE>& clipOrder, vector<NodeVolumeCuts>& output);

// this a cheat to recalculate plane normals after scaling a solid. Really I should get the plane
Expand Down Expand Up @@ -210,6 +214,8 @@ class Bsp

void update_lump_pointers();

void write_obj_file();

private:
int remove_unused_lightmaps(bool* usedFaces);
int remove_unused_visdata(bool* usedLeaves, BSPLEAF* oldLeaves, int oldLeafCount); // called after removing unused leaves
Expand Down
Loading

0 comments on commit 3dd3556

Please sign in to comment.