From 71626dbc76db89871cb164128946f2b9207a781a Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 31 Mar 2023 01:41:31 -0700 Subject: [PATCH] K_GetBestWaypointForMobj: add a hint argument The hint argument is a known nearby waypoint that can be used to optimize the waypoint search. --- src/k_kart.c | 2 +- src/k_waypoint.cpp | 32 +++++++++++++++++++------------- src/k_waypoint.h | 3 ++- src/objects/spb.c | 4 ++-- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index d90e4e98c..cbb0e6d53 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8358,7 +8358,7 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player) if ((player != NULL) && (player->mo != NULL) && (P_MobjWasRemoved(player->mo) == false)) { - waypoint_t *waypoint = K_GetBestWaypointForMobj(player->mo); + waypoint_t *waypoint = K_GetBestWaypointForMobj(player->mo, NULL); boolean updaterespawn = false; // Our current waypoint. diff --git a/src/k_waypoint.cpp b/src/k_waypoint.cpp index 70613e598..191a751ba 100644 --- a/src/k_waypoint.cpp +++ b/src/k_waypoint.cpp @@ -343,11 +343,11 @@ static void K_CompareOverlappingWaypoint } /*-------------------------------------------------- - waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj) + waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj, waypoint_t *const hint) See header file for description. --------------------------------------------------*/ -waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj) +waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj, waypoint_t *const hint) { waypoint_t *bestwaypoint = NULL; @@ -357,21 +357,15 @@ waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj) } else { - size_t i = 0U; - waypoint_t *checkwaypoint = NULL; fixed_t closestdist = INT32_MAX; fixed_t checkdist = INT32_MAX; fixed_t bestfindist = INT32_MAX; - for (i = 0; i < numwaypoints; i++) + auto sort_waypoint = [&](waypoint_t *const checkwaypoint) { - fixed_t rad; - - checkwaypoint = &waypointheap[i]; - if (!K_GetWaypointIsEnabled(checkwaypoint)) { - continue; + return; } checkdist = P_AproxDistance( @@ -379,7 +373,7 @@ waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj) (mobj->y / FRACUNIT) - (checkwaypoint->mobj->y / FRACUNIT)); checkdist = P_AproxDistance(checkdist, ((mobj->z / FRACUNIT) - (checkwaypoint->mobj->z / FRACUNIT)) * 4); - rad = (checkwaypoint->mobj->radius / FRACUNIT); + fixed_t rad = (checkwaypoint->mobj->radius / FRACUNIT); // remember: huge radius if (closestdist <= rad && checkdist <= rad && finishline != NULL) @@ -387,7 +381,7 @@ waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj) if (!P_TraceWaypointTraversal(mobj, checkwaypoint->mobj)) { // Save sight checks when all of the other checks pass, so we only do it if we have to - continue; + return; } // If the mobj is touching multiple waypoints at once, @@ -405,12 +399,24 @@ waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj) if (!P_TraceWaypointTraversal(mobj, checkwaypoint->mobj)) { // Save sight checks when all of the other checks pass, so we only do it if we have to - continue; + return; } bestwaypoint = checkwaypoint; closestdist = checkdist; } + }; + + if (hint != NULL) + { + // The hint is a waypoint that is already known to be close to the player. It is used to exclude + // most of the other waypoints by distance so fewer expensive sight checks are performed. + sort_waypoint(hint); + } + + for (size_t i = 0U; i < numwaypoints; i++) + { + sort_waypoint(&waypointheap[i]); } } diff --git a/src/k_waypoint.h b/src/k_waypoint.h index 051798036..fce73bebc 100644 --- a/src/k_waypoint.h +++ b/src/k_waypoint.h @@ -196,11 +196,12 @@ waypoint_t *K_GetClosestWaypointToMobj(mobj_t *const mobj); Input Arguments:- mobj - mobj to get the waypoint for. + hint - a previously known nearby waypoint to optimize searching. Return:- The best waypoint for the mobj, or NULL if there were no matches --------------------------------------------------*/ -waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj); +waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj, waypoint_t *const hint); /*-------------------------------------------------- diff --git a/src/objects/spb.c b/src/objects/spb.c index 6ed876522..722fc4eee 100644 --- a/src/objects/spb.c +++ b/src/objects/spb.c @@ -403,7 +403,7 @@ static void SPBSeek(mobj_t *spb, mobj_t *bestMobj) if (spb_curwaypoint(spb) == -1) { // Determine first waypoint. - curWaypoint = K_GetBestWaypointForMobj(spb); + curWaypoint = K_GetBestWaypointForMobj(spb, NULL); spb_curwaypoint(spb) = (INT32)K_GetWaypointHeapIndex(curWaypoint); } else @@ -421,7 +421,7 @@ static void SPBSeek(mobj_t *spb, mobj_t *bestMobj) } else { - destWaypoint = K_GetBestWaypointForMobj(bestMobj); + destWaypoint = K_GetBestWaypointForMobj(bestMobj, NULL); } if (curWaypoint != NULL)