mirror of
https://github.com/nzp-team/dquakeplus.git
synced 2025-02-16 08:31:43 +00:00
Remove get_closest_waypoint prototype functions
This commit is contained in:
parent
4c6eaf0a2a
commit
2c65089a2c
3 changed files with 0 additions and 496 deletions
332
source/pr_cmds.c
332
source/pr_cmds.c
|
@ -1896,129 +1896,6 @@ qboolean ofs_tracebox(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int ty
|
|||
|
||||
|
||||
|
||||
typedef struct nearest_walkable_waypoint_results_s {
|
||||
int best_tracebox_waypoint_idx;
|
||||
float best_tracebox_waypoint_dist_squared;
|
||||
int best_traceline_waypoint_idx;
|
||||
float best_tracline_waypoint_dist_squared;
|
||||
} nearest_walkable_waypoint_results_t;
|
||||
|
||||
|
||||
//
|
||||
// Recursive K-D tree nearest-neighbor lookup on waypoints
|
||||
// Searches the subtree with node `waypoint_idx` as the root
|
||||
//
|
||||
void nearest_walkable_waypoint_kdtree(int waypoint_idx, edict_t *ent, int debug_level, nearest_walkable_waypoint_results_t *result) {
|
||||
float waypoint_dist_squared = VectorDistanceSquared(ent->v.origin, waypoints[waypoint_idx].origin);
|
||||
if(waypoint_dist_squared < result->best_tracebox_waypoint_dist_squared) {
|
||||
if(ofs_tracebox(ent->v.origin, ai_hull_mins, ai_hull_maxs, waypoints[waypoint_idx].origin, MOVE_NOMONSTERS, ent)) {
|
||||
result->best_tracebox_waypoint_dist_squared = waypoint_dist_squared;
|
||||
result->best_tracebox_waypoint_idx = waypoint_idx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(developer.value == 3) {
|
||||
for(int i = -1; i < debug_level; i++) {
|
||||
Con_Printf("\t");
|
||||
}
|
||||
Con_Printf("kd after checking node %d with dist: %.2f, cur best: %d with dist: %.2f\n",
|
||||
waypoint_idx,
|
||||
waypoint_dist_squared,
|
||||
result->best_tracebox_waypoint_idx,
|
||||
result->best_tracebox_waypoint_dist_squared
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
int axis = waypoints_kdtree_axis[waypoint_idx];
|
||||
int halfspace_child_idx;
|
||||
int other_halfspace_child_idx;
|
||||
|
||||
if(ent->v.origin[axis] <= waypoints[waypoint_idx].origin[axis]) {
|
||||
halfspace_child_idx = waypoints_kdtree_left_child_node[waypoint_idx];
|
||||
other_halfspace_child_idx = waypoints_kdtree_right_child_node[waypoint_idx];
|
||||
}
|
||||
else {
|
||||
halfspace_child_idx = waypoints_kdtree_right_child_node[waypoint_idx];
|
||||
other_halfspace_child_idx = waypoints_kdtree_left_child_node[waypoint_idx];
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(developer.value == 3) {
|
||||
for(int i = -1; i < debug_level; i++) {
|
||||
Con_Printf("\t");
|
||||
}
|
||||
if(ent->v.origin[axis] <= waypoints[waypoint_idx].origin[axis]) {
|
||||
Con_Printf("kd - Query point (%.2f, %.2f, %.2f) in left half-space of node %d at (%.2f, %.2f, %.2f) on axis %d. Left child: %d, Right child: %d\n",
|
||||
ent->v.origin[0], ent->v.origin[1], ent->v.origin[2],
|
||||
waypoint_idx,
|
||||
waypoints[waypoint_idx].origin[0], waypoints[waypoint_idx].origin[1], waypoints[waypoint_idx].origin[2],
|
||||
axis,
|
||||
waypoints_kdtree_left_child_node[waypoint_idx],
|
||||
waypoints_kdtree_right_child_node[waypoint_idx]
|
||||
);
|
||||
}
|
||||
else {
|
||||
Con_Printf("kd - Query point (%.2f, %.2f, %.2f) in right half-space of node %d at (%.2f, %.2f, %.2f) on axis %d. Left child: %d, Right child: %d\n",
|
||||
ent->v.origin[0], ent->v.origin[1], ent->v.origin[2],
|
||||
waypoint_idx,
|
||||
waypoints[waypoint_idx].origin[0], waypoints[waypoint_idx].origin[1], waypoints[waypoint_idx].origin[2],
|
||||
axis,
|
||||
waypoints_kdtree_left_child_node[waypoint_idx],
|
||||
waypoints_kdtree_right_child_node[waypoint_idx]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if(halfspace_child_idx >= 0) {
|
||||
nearest_walkable_waypoint_kdtree(halfspace_child_idx, ent, debug_level + 1, result);
|
||||
}
|
||||
|
||||
// // Check if the other half-space is closer than the best point so far
|
||||
if(other_halfspace_child_idx >= 0) {
|
||||
float other_halfspace_dist_squared = (ent->v.origin[axis] - waypoints[waypoint_idx].origin[axis]);
|
||||
other_halfspace_dist_squared *= other_halfspace_dist_squared;
|
||||
if(other_halfspace_dist_squared < result->best_tracebox_waypoint_dist_squared) {
|
||||
|
||||
if(developer.value == 3) {
|
||||
for(int i = -1; i < debug_level; i++) {
|
||||
Con_Printf("\t");
|
||||
}
|
||||
Con_Printf("kd - Query point (%.2f, %.2f, %.2f) dist to half-space plane of node %d at (%.2f, %.2f, %.2f) on axis %d = %.2f < cur best node dist: %.2f -- checking opposite half-space\n",
|
||||
ent->v.origin[0], ent->v.origin[1], ent->v.origin[2],
|
||||
waypoint_idx,
|
||||
waypoints[waypoint_idx].origin[0], waypoints[waypoint_idx].origin[1], waypoints[waypoint_idx].origin[2],
|
||||
axis,
|
||||
other_halfspace_dist_squared,
|
||||
result->best_tracebox_waypoint_dist_squared
|
||||
);
|
||||
}
|
||||
|
||||
nearest_walkable_waypoint_kdtree(other_halfspace_child_idx, ent, debug_level + 1, result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(developer.value == 3) {
|
||||
for(int i = -1; i < debug_level; i++) {
|
||||
Con_Printf("\t");
|
||||
}
|
||||
Con_Printf("kd after checking node %d children: cur best: %d with dist: %.2f\n",
|
||||
result->best_tracebox_waypoint_idx,
|
||||
result->best_tracebox_waypoint_dist_squared
|
||||
);
|
||||
}
|
||||
|
||||
// return best_waypoint_idx;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Returns the clsoest waypoint to an entity that the entity can walk to
|
||||
|
@ -2058,215 +1935,6 @@ int get_closest_waypoint(int entnum) {
|
|||
return best_waypoint_idx;
|
||||
}
|
||||
|
||||
//
|
||||
// Returns the clsoest waypoint to an entity that the entity can walk to
|
||||
// Uses K-D tree lookup
|
||||
//
|
||||
int get_closest_waypoint_v1(int entnum) {
|
||||
trace_t trace;
|
||||
edict_t *ent = EDICT_NUM(entnum);
|
||||
int waypoint_idx = -1;
|
||||
|
||||
|
||||
nearest_walkable_waypoint_results_t nearest_waypoint_result;
|
||||
nearest_waypoint_result.best_tracebox_waypoint_idx = -1;
|
||||
nearest_waypoint_result.best_tracebox_waypoint_dist_squared = INFINITY;
|
||||
nearest_waypoint_result.best_traceline_waypoint_idx = -1;
|
||||
nearest_waypoint_result.best_tracline_waypoint_dist_squared = INFINITY;
|
||||
|
||||
|
||||
vec3_t ent_mins;
|
||||
vec3_t ent_maxs;
|
||||
VectorCopy(ai_hull_mins, ent_mins);
|
||||
VectorCopy(ai_hull_maxs, ent_maxs);
|
||||
|
||||
if(developer.value == 3) {
|
||||
Con_Printf("get_closest_waypoint -- For ent: %d at (%.2f, %.2f, %.2f), prev cloest way: %d, cur dist: %.2f \n",
|
||||
entnum,
|
||||
ent->v.origin[0], ent->v.origin[1], ent->v.origin[2],
|
||||
closest_waypoints[entnum],
|
||||
closest_waypoints[entnum] < 0 ? NAN : VectorDistanceSquared(ent->v.origin, waypoints[closest_waypoints[entnum]].origin)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
int prev_closest_way = closest_waypoints[entnum];
|
||||
// Check if the prior closest waypoint is still walkable, if so set that as upper limit when comparing against other waypoints
|
||||
if(prev_closest_way >= 0) {
|
||||
// Try against the prev waypoint first
|
||||
if(ofs_tracebox(ent->v.origin, ent_mins, ent_maxs, waypoints[prev_closest_way].origin, MOVE_NOMONSTERS, ent)) {
|
||||
nearest_waypoint_result.best_tracebox_waypoint_idx = prev_closest_way;
|
||||
nearest_waypoint_result.best_tracebox_waypoint_dist_squared = VectorDistanceSquared(waypoints[prev_closest_way].origin, ent->v.origin);
|
||||
|
||||
|
||||
if(developer.value == 3) {
|
||||
Con_Printf("\tget_closest_waypoint -- Can walk to prev waypoint %d at dist: %.2f\n",
|
||||
nearest_waypoint_result.best_tracebox_waypoint_idx,
|
||||
nearest_waypoint_result.best_tracebox_waypoint_dist_squared
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(waypoints_kdtree_root_node >= 0) {
|
||||
nearest_walkable_waypoint_kdtree( waypoints_kdtree_root_node, ent, 0, &nearest_waypoint_result);
|
||||
waypoint_idx = nearest_waypoint_result.best_tracebox_waypoint_idx;
|
||||
}
|
||||
|
||||
|
||||
if(developer.value == 3) {
|
||||
Con_Printf("\tget_closest_waypoint -- Final best waypoint %d at dist: %.2f\n",
|
||||
nearest_waypoint_result.best_tracebox_waypoint_idx,
|
||||
nearest_waypoint_result.best_tracebox_waypoint_dist_squared
|
||||
);
|
||||
}
|
||||
|
||||
closest_waypoints[entnum] = waypoint_idx;
|
||||
return waypoint_idx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Returns the closest waypoint to an entity that the entity can walk to
|
||||
//
|
||||
int get_closest_waypoint_v0(int entnum) {
|
||||
// int get_closest_waypoint(int entnum) {
|
||||
trace_t trace;
|
||||
edict_t *ent = EDICT_NUM(entnum);
|
||||
|
||||
// Keep track of the closest waypoint that...
|
||||
int best_traceline_way = -1; // ... we are able to traceline to
|
||||
int best_tracebox_way = -1; // ... we are able to tracebox to
|
||||
float best_traceline_way_dist = max_waypoint_distance * max_waypoint_distance;
|
||||
float best_tracebox_way_dist = max_waypoint_distance * max_waypoint_distance;
|
||||
|
||||
|
||||
// Start the search from the last known closest waypoint and its neighbors
|
||||
// Assuming that at least one of the previous waypoint and its neighbors
|
||||
// is still traceline-able to, we'll easily skip tracelining against most
|
||||
// map waypoints that are farther away.
|
||||
int prev_closest_way = closest_waypoints[entnum];
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// New logic:
|
||||
// ------------------------------------------------------------------------
|
||||
// Try traceboxing against prev waypoint / its neighbors
|
||||
// If we traceboxed against any, that's the best and skip to checking against all
|
||||
// Successful tracebox implies successful traceline
|
||||
//
|
||||
// If we have a waypoint we've traceboxed against, don't bother tracelining
|
||||
// against waypoints, we already know which we're going to return in the
|
||||
// worst-case.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
|
||||
if(prev_closest_way >= 0) {
|
||||
// Try against the prev waypoint first
|
||||
trace = SV_Move(ent->v.origin, vec3_origin, vec3_origin, waypoints[prev_closest_way].origin, MOVE_NOMONSTERS, ent);
|
||||
if(trace.fraction >= 1) {
|
||||
best_traceline_way_dist = VectorDistanceSquared(waypoints[prev_closest_way].origin, ent->v.origin);
|
||||
best_traceline_way = prev_closest_way;
|
||||
}
|
||||
// Otherwise, try against its neighbors
|
||||
else {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
int neighbor_way = waypoints[prev_closest_way].target[i];
|
||||
// Skip unused neighbor slots / unused waypoint slots / inactive waypoints
|
||||
if (neighbor_way < 0 || !waypoints[neighbor_way].used || !waypoints[neighbor_way].open) {
|
||||
continue;
|
||||
}
|
||||
float dist = VectorDistanceSquared(waypoints[neighbor_way].origin, ent->v.origin);
|
||||
if(dist < best_traceline_way_dist || best_traceline_way == -1) {
|
||||
trace = SV_Move(ent->v.origin, vec3_origin, vec3_origin, waypoints[neighbor_way].origin, MOVE_NOMONSTERS, ent);
|
||||
if (trace.fraction >= 1) {
|
||||
best_traceline_way_dist = dist;
|
||||
best_traceline_way = neighbor_way;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try against the prev waypoint first
|
||||
if(ofs_tracebox(ent->v.origin, ent->v.mins, ent->v.maxs, waypoints[prev_closest_way].origin, MOVE_NOMONSTERS, ent)) {
|
||||
best_tracebox_way_dist = VectorDistanceSquared(waypoints[prev_closest_way].origin, ent->v.origin);
|
||||
best_tracebox_way = prev_closest_way;
|
||||
}
|
||||
// Otherwise, try against its neighbors
|
||||
else {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
int neighbor_way = waypoints[prev_closest_way].target[i];
|
||||
// Skip unused neighbor slots / unused waypoint slots / inactive waypoints
|
||||
if (neighbor_way < 0 || !waypoints[neighbor_way].used || !waypoints[neighbor_way].open) {
|
||||
continue;
|
||||
}
|
||||
float dist = VectorDistanceSquared(waypoints[neighbor_way].origin, ent->v.origin);
|
||||
if(dist < best_tracebox_way_dist || best_tracebox_way == -1) {
|
||||
if(ofs_tracebox(ent->v.origin, ent->v.mins, ent->v.maxs, waypoints[neighbor_way].origin, MOVE_NOMONSTERS, ent)) {
|
||||
best_tracebox_way_dist = dist;
|
||||
best_tracebox_way = neighbor_way;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now we may have an initial valid `best_traceline_way` / `best_traceline_way_dist`
|
||||
// We can safely skip all waypoints farther away than this
|
||||
|
||||
for(int i = 0; i < n_waypoints; i++) {
|
||||
// Skip unused waypoint slots / inactive waypoints
|
||||
if(!waypoints[i].used || !waypoints[i].open) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float dist = VectorDistanceSquared(waypoints[i].origin, ent->v.origin);
|
||||
|
||||
// If we have a `best_tracebox_way`, that will take precedence as a return value over any traceline-able waypoint.
|
||||
// Therefore, if we know of a waypoint that we can tracebox to, skip all traceline checks against all waypoints
|
||||
if(best_tracebox_way == -1) {
|
||||
if((i != best_traceline_way && dist < best_traceline_way_dist) || best_traceline_way == -1) {
|
||||
trace = SV_Move(ent->v.origin, vec3_origin, vec3_origin, waypoints[i].origin, MOVE_NOMONSTERS, ent);
|
||||
if(trace.fraction >= 1) {
|
||||
best_traceline_way_dist = dist;
|
||||
best_traceline_way = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if((i != best_tracebox_way && dist < best_tracebox_way_dist) || best_tracebox_way == -1) {
|
||||
if(ofs_tracebox(ent->v.origin, ent->v.mins, ent->v.maxs, waypoints[i].origin, MOVE_NOMONSTERS, ent)) {
|
||||
best_tracebox_way_dist = dist;
|
||||
best_tracebox_way = i;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int best_way = -1;
|
||||
|
||||
// If we can tracebox to any waypoint, return the closest one:
|
||||
if(best_tracebox_way >= 0) {
|
||||
best_way = best_tracebox_way;
|
||||
}
|
||||
// Otherwise, return the best waypoint we found that we can traceline to
|
||||
// (which may be none for some if a map's waypoints aren't great)
|
||||
else {
|
||||
best_way = best_traceline_way;
|
||||
}
|
||||
|
||||
// Cache the closest waypoint to this entity, so that we start the next search from this same waypoint and its neighbors
|
||||
closest_waypoints[entnum] = best_way;
|
||||
|
||||
return best_way;
|
||||
}
|
||||
|
||||
|
||||
void Do_Pathfind (void) {
|
||||
|
|
|
@ -356,11 +356,6 @@ extern waypoint_ai waypoints[MAX_WAYPOINTS];
|
|||
extern int n_waypoints;
|
||||
extern short closest_waypoints[MAX_EDICTS];
|
||||
|
||||
extern int waypoints_kdtree_root_node;
|
||||
extern int waypoints_kdtree_left_child_node[MAX_WAYPOINTS];
|
||||
extern int waypoints_kdtree_right_child_node[MAX_WAYPOINTS];
|
||||
extern int waypoints_kdtree_axis[MAX_WAYPOINTS];
|
||||
|
||||
|
||||
|
||||
// thread structs
|
||||
|
|
159
source/sv_main.c
159
source/sv_main.c
|
@ -1388,11 +1388,6 @@ void W_stov (char *v, vec3_t out)
|
|||
|
||||
waypoint_ai waypoints[MAX_WAYPOINTS];
|
||||
int n_waypoints;
|
||||
int waypoints_kdtree_root_node;
|
||||
int waypoints_kdtree_left_child_node[MAX_WAYPOINTS];
|
||||
int waypoints_kdtree_right_child_node[MAX_WAYPOINTS];
|
||||
int waypoints_kdtree_axis[MAX_WAYPOINTS];
|
||||
|
||||
|
||||
|
||||
//
|
||||
|
@ -1505,157 +1500,6 @@ void Load_Waypoint_NZPBETA() {
|
|||
W_fclose(h);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int build_waypoints_kdsubtree(int *sublist_waypoint_idxs, int sublist_n_waypoints, int *kdtree_left_child_nodes, int *kdtree_right_child_nodes, int *kdtree_axis, int level) {
|
||||
if(sublist_n_waypoints <= 0) {
|
||||
return -1;
|
||||
}
|
||||
// int axis = level % 3; // At each level, iterate through 3D space axes (x,y,z)
|
||||
int axis;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Determine which axis to split on: Whichever has the largest spatial extent
|
||||
// ------------------------------------------------------------------------
|
||||
// axis = level % 3;
|
||||
// -----------------
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
VectorCopy(waypoints[sublist_waypoint_idxs[0]].origin, mins);
|
||||
VectorCopy(waypoints[sublist_waypoint_idxs[0]].origin, maxs);
|
||||
for(int i = 1; i < sublist_n_waypoints; i++) {
|
||||
int waypoint_idx = sublist_waypoint_idxs[i];
|
||||
VectorMin(mins, waypoints[waypoint_idx].origin, mins);
|
||||
VectorMax(maxs, waypoints[waypoint_idx].origin, maxs);
|
||||
}
|
||||
vec3_t spatial_extent;
|
||||
VectorSubtract(maxs, mins, spatial_extent);
|
||||
|
||||
// Pick largest axis:
|
||||
float max_extent = fmax(spatial_extent[0], fmax(spatial_extent[1], spatial_extent[2]));
|
||||
axis = (spatial_extent[0] >= max_extent) ? 0 : (spatial_extent[1] >= max_extent) ? 1 : 2;
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
// Con_Printf("kdtree - building subtree at level: %d\n", level);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// The root node for this subtree will bee the median waypoint along the axis
|
||||
//
|
||||
// To find the median, sort the waypoints by their value along the axis
|
||||
// and take the middle waypoint
|
||||
// ------------------------------------------------------------------------
|
||||
argsort_entry_t waypoint_sort_values[MAX_WAYPOINTS];
|
||||
for(int i = 0; i < sublist_n_waypoints; i++) {
|
||||
waypoint_sort_values[i].index = sublist_waypoint_idxs[i];
|
||||
waypoint_sort_values[i].value = waypoints[sublist_waypoint_idxs[i]].origin[axis];
|
||||
}
|
||||
// Con_Printf("\tkdtree - about to call qsort for %d waypoints\n", sublist_n_waypoints);
|
||||
qsort(waypoint_sort_values, sublist_n_waypoints, sizeof(argsort_entry_t), argsort_comparator);
|
||||
// Con_Printf("\tkdtree - qsort done\n");
|
||||
// Con_Printf("\tkdtree - qsort list: [");
|
||||
// for(int i = 0; i < sublist_n_waypoints; i++) {
|
||||
// Con_Printf("(%d, %d, %.2f), ", i, waypoint_sort_values[i].index, waypoint_sort_values[i].value);
|
||||
// }
|
||||
// Con_Printf("]\n");
|
||||
int median_waypoint_idx = waypoint_sort_values[sublist_n_waypoints / 2].index;
|
||||
// Con_Printf("\tkdtree - qsort done, median waypoint idx: %d\n", median_waypoint_idx);
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Split all waypoints in this subtree into left / right half-spaces
|
||||
int left_waypoint_idxs[MAX_WAYPOINTS];
|
||||
int right_waypoint_idxs[MAX_WAYPOINTS];
|
||||
int n_left_waypoints = 0;
|
||||
int n_right_waypoints = 0;
|
||||
|
||||
for(int i = 0; i < sublist_n_waypoints; i++) {
|
||||
int waypoint_idx = sublist_waypoint_idxs[i];
|
||||
if(waypoint_idx == median_waypoint_idx) {
|
||||
continue;
|
||||
}
|
||||
if(waypoints[waypoint_idx].origin[axis] <= waypoints[median_waypoint_idx].origin[axis]) {
|
||||
// Con_Printf("\t\tkdtree - (%d, %.2f) <= (%d, %.2f)\n", waypoint_idx, waypoints[waypoint_idx].origin[axis], median_waypoint_idx, waypoints[median_waypoint_idx].origin[axis]);
|
||||
left_waypoint_idxs[n_left_waypoints++] = waypoint_idx;
|
||||
}
|
||||
else {
|
||||
// Con_Printf("\t\tkdtree - (%d, %.2f) > (%d, %.2f)\n", waypoint_idx, waypoints[waypoint_idx].origin[axis], median_waypoint_idx, waypoints[median_waypoint_idx].origin[axis]);
|
||||
right_waypoint_idxs[n_right_waypoints++] = waypoint_idx;
|
||||
}
|
||||
}
|
||||
|
||||
// Con_Printf("\tkdtree - Left subtree: %d, Right subtree: %d\n", n_left_waypoints, n_right_waypoints);
|
||||
|
||||
kdtree_left_child_nodes[median_waypoint_idx] = build_waypoints_kdsubtree(left_waypoint_idxs, n_left_waypoints, kdtree_left_child_nodes, kdtree_right_child_nodes, kdtree_axis, level+1);
|
||||
kdtree_right_child_nodes[median_waypoint_idx] = build_waypoints_kdsubtree(right_waypoint_idxs, n_right_waypoints, kdtree_left_child_nodes, kdtree_right_child_nodes, kdtree_axis, level+1);
|
||||
kdtree_axis[median_waypoint_idx] = axis;
|
||||
return median_waypoint_idx;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Constructs a K-D tree from the loaded waypoints for efficient nearest-neighbor lookup
|
||||
//
|
||||
void build_waypoints_kdtree() {
|
||||
int n_waypoint_idxs = 0;
|
||||
int all_waypoint_idxs[MAX_WAYPOINTS];
|
||||
|
||||
// Build a contiguous list of valid waypoint indices in the global waypoints array
|
||||
for(int i = 0; i < MAX_WAYPOINTS; i++) {
|
||||
// Skip empty waypoint slots in waypoints list
|
||||
if(waypoints[i].used) {
|
||||
all_waypoint_idxs[n_waypoint_idxs++] = i;
|
||||
}
|
||||
|
||||
// Initialize values:
|
||||
waypoints_kdtree_left_child_node[i] = -1;
|
||||
waypoints_kdtree_right_child_node[i] = -1;
|
||||
waypoints_kdtree_axis[i] = 0;
|
||||
|
||||
}
|
||||
// Con_Printf("About to build waypoints KD tree\n");
|
||||
waypoints_kdtree_root_node = build_waypoints_kdsubtree(all_waypoint_idxs, n_waypoint_idxs, waypoints_kdtree_left_child_node, waypoints_kdtree_right_child_node, waypoints_kdtree_axis, 0);
|
||||
|
||||
Con_Printf("Root waypoint idx: %d\n", waypoints_kdtree_root_node);
|
||||
for(int i = 0; i < n_waypoints; i++) {
|
||||
Con_Printf("{'waypoint_idx': %d, 'pos': [%.2f, %.2f, %.2f], 'axis': %d, 'left_child_idx': %d, 'right_child_idx': %d}\n",
|
||||
i,
|
||||
waypoints[i].origin[0], waypoints[i].origin[1], waypoints[i].origin[2],
|
||||
waypoints_kdtree_axis[i],
|
||||
waypoints_kdtree_left_child_node[i],
|
||||
waypoints_kdtree_right_child_node[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
extern int get_closest_waypoint(int entnum);
|
||||
|
||||
void benchmark_waypoints() {
|
||||
Con_Printf("============== Benchmark Start ==============\n");
|
||||
|
||||
int n_iters = 100;
|
||||
for(int i = 0; i < n_waypoints; i++) {
|
||||
for(int j = 0; j < n_iters; j++) {
|
||||
vec3_t query_point;
|
||||
// Move 50 qu along x-axis
|
||||
VectorCopy(waypoints[i].origin, query_point);
|
||||
query_point[0] += 50;
|
||||
|
||||
// Yes, this is cursed, but I need to set query point
|
||||
int entnum = 1;
|
||||
edict_t *ent = EDICT_NUM(entnum);
|
||||
VectorCopy(query_point, ent->v.origin);
|
||||
|
||||
int closest_waypoint = get_closest_waypoint(entnum);
|
||||
}
|
||||
}
|
||||
Con_Printf("============== Benchmark Done ==============\n");
|
||||
}
|
||||
|
||||
//
|
||||
// Some waypoint slots in the global list may not have been loaded
|
||||
// Look for these empty slots, and shift all waypoints down to fill them
|
||||
|
@ -1741,7 +1585,6 @@ void Load_Waypoint () {
|
|||
Con_DPrintf("No waypoint file (%s/maps/%s.way) found, trying beta format..\n", com_gamedir, sv.name);
|
||||
Load_Waypoint_NZPBETA();
|
||||
cleanup_waypoints();
|
||||
build_waypoints_kdtree();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1836,8 +1679,6 @@ void Load_Waypoint () {
|
|||
W_fclose(h);
|
||||
//Z_Free (w_string_temp);
|
||||
cleanup_waypoints();
|
||||
build_waypoints_kdtree();
|
||||
benchmark_waypoints();
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue