quakec/source/shared/navmesh_defines.qc

104 lines
3.9 KiB
C++

//A single navmesh vertex
struct navmesh_vertex
{
vector pos;
};
//Either a tri or a quad
struct navmesh_poly
{
float verts[4];
float vert_count;
string doortarget; // "" or matches the .wayTarget field of a door entity. Polygon is only used when door is open (i.e. door.state == STATE_BOTTOM)
int entrance_edge; // If != -1, specifies which edge index this polygon can be entered from. (0,1,2, or 3)
//The following fields are only used for actually pathfinding on the navmesh
//The values are calculated in the editor when the navmesh is saved, but are not assigned in the editor before that.
//These values are saved in the navmesh file, and loaded into the server's navmesh
//FIXME: Unhandled edge case when a polygon shares a single edge with more than one polygon (like dropping down from a ledge)
float connected_polies_count;//How many polygons we share an edge with
float connected_polies[4];//Index of the polygons that we share an edge with (similar to links), more than 4 should be impossible (FIXME: highly unlikely)
float connected_polies_left_vert[4];//The left vertex of the shared edge
float connected_polies_right_vert[4];//The right vertex of the shared edge
float connected_polies_neighbor_edge_index[4]; // conected_polies_neighbor_edge_index[i] holds the ith neighbor's edge index we are traversing to enter the neighbor polygon. This is used for polygons that may only be entered from a specific direction.
vector center;//The center of the polygon in 3D space (pre-calculated because why calculate it at runtime)
};
#define NAV_MAX_VERTS 1024
#define NAV_MAX_POLIES 512
// ============================================================================
// Shared Navmesh functions used by both client and server
// ============================================================================
//Returns the distance between the 2d line l1->l2 and pos
float navmesh_2D_line_point_dist(vector l1, vector l2, vector pos)
{
float dot = (l2 - l1) * (pos - l2);
if(dot > 0)
return vlen(l2 - pos);
dot = (l1 - l2) * (pos - l1);
if(dot > 0)
return vlen(l1 - pos);
//2D cross product between (next_vert-vert) and (pos-vert)
//float dist = (l2.x - l1.x) * (pos.y - l1.y) - (l2.y - l1.y) * (pos.y - l1.y);
//dist = dist / vlen(l1 - l2);
float dist = vlen(crossproduct(l2-l1,l1-pos))/vlen(l1-l2);
return fabs(dist);
}
//============= Navmesh Pathfind Defs =============
#define PATHFIND_POLY_SET_NONE 0
#define PATHFIND_POLY_SET_OPEN 1
#define PATHFIND_POLY_SET_CLOSED 2
struct pathfind_result
{
//Contains the set that the ith polygon is in
float poly_set[NAV_MAX_POLIES];
//Contains the index of the last polygon that we used to get to the ith polygon
float poly_prev[NAV_MAX_POLIES];
//Contains the g-score of the ith polygon (distance from start node to ith node along the node path)
float poly_g_score[NAV_MAX_POLIES];
//f score = g score + h score
float poly_f_score[NAV_MAX_POLIES];
//Holds list of polygons in the path (indices of polygons from start to goal)
float result_node_path[NAV_MAX_POLIES];
//How many polies are in the path
float result_node_length;
//Together, these two arrays hold the list of polygon edges we cross on the path
float portals_left_vert[NAV_MAX_POLIES];
float portals_right_vert[NAV_MAX_POLIES];
//How many portals are in the pathfind_portals_left_vert (same as pathfind_result_node_length - 1)
float portals_length;
//Final resultant path:
//Contains a list of points that makes up the path
vector result_path[NAV_MAX_POLIES];
//How many points are in the path
float result_length;
};
//Returns some number > 0 if point p is to the left of line a->b
//Returns some number < 0 if point is to the right of line a->b
//Returns 0 if point is on the line
//(Left / Right is defined in the xy plane, z=0)
float pathfind_point_is_to_left(vector a, vector b, vector p)
{
return (b.x - a.x)*(p.y - a.y) - (b.y - a.y)*(p.x - a.x);
}
// ============================================================================