Skip to content

Commit

Permalink
use ladders to for cheap nav mesh links
Browse files Browse the repository at this point in the history
also refactor and penalize flying to leaves that aren't lower than the current leaf
  • Loading branch information
wootguy committed Jul 7, 2024
1 parent 11e3ebd commit 4e26714
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 100 deletions.
4 changes: 2 additions & 2 deletions src/editor/BspRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -958,12 +958,12 @@ void BspRenderer::generateNavMeshBuffer() {
}

void BspRenderer::generateLeafNavMeshBuffer() {
int hull = 3;
int hull = NAV_HULL;
RenderClipnodes* renderClip = &renderClipnodes[0];
renderClip->clipnodeBuffer[hull] = NULL;
renderClip->wireframeClipnodeBuffer[hull] = NULL;

LeafNavMesh* navMesh = LeafNavMeshGenerator().generate(map, hull);
LeafNavMesh* navMesh = LeafNavMeshGenerator().generate(map);
g_app->debugLeafNavMesh = navMesh;

static COLOR4 hullColors[] = {
Expand Down
47 changes: 21 additions & 26 deletions src/nav/LeafNavMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@
#include <limits.h>

LeafNode::LeafNode() {
links.clear();
leafFaces.clear();
id = -1;
center = bottom = top = mins = maxs = vec3();
entidx = 0;
center = origin = mins = maxs = vec3();
}

bool LeafNode::isInside(vec3 p) {
Expand All @@ -42,25 +41,31 @@ bool LeafNode::addLink(int node, Polygon3D linkArea) {
link.linkArea = linkArea;
link.node = node;

link.bottom = linkArea.center;
link.pos = linkArea.center;
if (fabs(linkArea.plane_z.z) < 0.7f) {
linkArea.intersect2D(linkArea.center, linkArea.center - vec3(0, 0, 4096), link.bottom);
link.bottom.z += NAV_BOTTOM_EPSILON;
// wall links should be positioned at the bottom of the intersection to keep paths near the floor
linkArea.intersect2D(linkArea.center, linkArea.center - vec3(0, 0, 4096), link.pos);
link.pos.z += NAV_BOTTOM_EPSILON;
}

links.push_back(link);

return true;
}

int LeafNode::numLinks() {
int numLinks = 0;

bool LeafNode::addLink(int node, vec3 linkPos) {
for (int i = 0; i < links.size(); i++) {
numLinks++;
if (links[i].node == node) {
return true;
}
}

return numLinks;
LeafLink link;
link.node = node;
link.pos = linkPos;
links.push_back(link);

return true;
}

LeafNavMesh::LeafNavMesh() {
Expand All @@ -72,21 +77,11 @@ void LeafNavMesh::clear() {
nodes.clear();
}

LeafNavMesh::LeafNavMesh(vector<LeafNode> inleaves) {
LeafNavMesh::LeafNavMesh(vector<LeafNode> inleaves, LeafOctree* octree) {
clear();

nodes = inleaves;

int totalSz = 0;
for (int i = 0; i < nodes.size(); i++) {
totalSz += sizeof(LeafNode) + (sizeof(LeafLink) * nodes[i].links.size());
}

logf("Created leaf nav mesh with %d leaves (%d KB)\n",
nodes.size(), totalSz / 1024);

logf("LeafNode = %d bytes, LeafLink = %d bytes\n",
sizeof(LeafNode), sizeof(LeafLink));
this->nodes = inleaves;
this->octree = octree;
}

bool LeafNavMesh::addLink(int from, int to, Polygon3D linkArea) {
Expand Down Expand Up @@ -196,7 +191,7 @@ float LeafNavMesh::path_cost(int a, int b) {

LeafNode& nodea = nodes[a];
LeafNode& nodeb = nodes[b];
vec3 delta = nodea.bottom - nodeb.bottom;
vec3 delta = nodea.origin - nodeb.origin;

for (int i = 0; i < nodea.links.size(); i++) {
LeafLink& link = nodea.links[i];
Expand Down Expand Up @@ -398,7 +393,7 @@ vector<int> LeafNavMesh::dijkstraRoute(int start, int end) {
for (int i = 1; i < path.size(); i++) {
LeafNode& mesha = nodes[path[i-1]];
LeafNode& meshb = nodes[path[i]];
len += (mesha.bottom - meshb.bottom).length();
len += (mesha.origin - meshb.origin).length();
cost += path_cost(path[i - 1], path[i]);
}
logf("Path length: %d, cost: %d\n", (int)len, (int)cost);
Expand Down
26 changes: 15 additions & 11 deletions src/nav/LeafNavMesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,40 @@
#define NAV_CROUCHJUMP_HEIGHT 63 // 208 gravity 50%
#define NAV_CROUCHJUMP_STACK_HEIGHT 135
#define NAV_AUTOCLIMB_HEIGHT 117
#define NAV_HULL 3

#define NAV_BOTTOM_EPSILON 1.0f // move waypoints this far from the bottom of the node

class Bsp;
class Entity;
class LeafOctree;

struct LeafLink {
int16_t node; // which leaf is linked to. -1 = end of links
Polygon3D linkArea; // region in which leaves are making contact
vec3 bottom; // centered at the bottom of the polygon intersection
uint16_t node; // which leaf is linked to
vec3 pos; // link position
float baseCost; // flat cost for using this path
float costMultiplier; // cost applied to length of path
bool useMiddleLink;

// for debugging
Polygon3D linkArea; // region in which leaves are making contact
};

struct LeafNode {
vector<LeafLink> links;
uint16_t id;
vec3 origin; // the best position for pathing (not necessarily the center)
int16_t entidx; // 0 for world leaves, else an entity leaf which may be relocated, enabled, or disabled

// for debugging
vec3 center;
vec3 bottom;
vec3 top;
vec3 mins;
vec3 maxs;
vec3 mins, maxs; // for octree insertion, not needed after generation
vector<Polygon3D> leafFaces;

LeafNode();

// adds a link to node "node" on edge "edge" with height difference "zDist"
bool addLink(int node, Polygon3D linkArea);
int numLinks();

bool addLink(int node, vec3 linkPos);

// returns true if point is inside leaf volume
bool isInside(vec3 p);
Expand All @@ -49,11 +52,12 @@ struct LeafNode {
class LeafNavMesh {
public:
vector<LeafNode> nodes;
LeafOctree* octree; // finds nearby leaves from any point in space, even outside of the BSP tree
uint16_t leafMap[MAX_MAP_CLIPNODE_LEAVES]; // maps a BSP leaf index to nav mesh node index

LeafNavMesh();

LeafNavMesh(vector<LeafNode> polys);
LeafNavMesh(vector<LeafNode> polys, LeafOctree* octree);

bool addLink(int from, int to, Polygon3D linkArea);

Expand Down
Loading

0 comments on commit 4e26714

Please sign in to comment.