1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2026-01-02 12:23:14 +00:00

Move getClosestPoint to a separate file

This commit is contained in:
elsid 2025-04-21 15:50:07 +02:00
parent 927b2bcceb
commit 3f1ac1848c
No known key found for this signature in database
GPG key ID: B845CB9FEE18AB40
8 changed files with 81 additions and 62 deletions

View file

@ -1,13 +1,11 @@
#include "aicombat.hpp"
#include <components/misc/coordinateconverter.hpp>
#include <components/misc/rng.hpp>
#include <components/esm3/aisequence.hpp>
#include <components/misc/mathutil.hpp>
#include <components/detournavigator/navigatorutils.hpp>
#include <components/esm3/aisequence.hpp>
#include <components/misc/coordinateconverter.hpp>
#include <components/misc/mathutil.hpp>
#include <components/misc/pathgridutils.hpp>
#include <components/misc/rng.hpp>
#include <components/sceneutil/positionattitudetransform.hpp>
#include "../mwphysics/raycasting.hpp"
@ -393,8 +391,8 @@ namespace MWMechanics
osg::Vec3f localPos = actor.getRefData().getPosition().asVec3();
coords.toLocal(localPos);
size_t closestPointIndex = PathFinder::getClosestPoint(pathgrid, localPos);
for (size_t i = 0; i < pathgrid->mPoints.size(); i++)
const std::size_t closestPointIndex = Misc::getClosestPoint(*pathgrid, localPos);
for (std::size_t i = 0; i < pathgrid->mPoints.size(); i++)
{
if (i != closestPointIndex
&& getPathGridGraph(pathgrid).isPointConnected(closestPointIndex, i))

View file

@ -2,12 +2,13 @@
#define GAME_MWMECHANICS_AICOMBAT_H
#include "aitemporarybase.hpp"
#include "aitimer.hpp"
#include "movement.hpp"
#include "typedaipackage.hpp"
#include "../mwworld/cellstore.hpp" // for Doors
#include "aitimer.hpp"
#include "movement.hpp"
#include <components/esm3/loadpgrd.hpp>
namespace ESM
{

View file

@ -16,6 +16,8 @@
namespace ESM
{
struct Cell;
struct Pathgrid;
namespace AiSequence
{
struct AiSequence;

View file

@ -8,6 +8,7 @@
#include <components/detournavigator/navigatorutils.hpp>
#include <components/esm3/aisequence.hpp>
#include <components/misc/coordinateconverter.hpp>
#include <components/misc/pathgridutils.hpp>
#include <components/misc/rng.hpp>
#include "../mwbase/environment.hpp"
@ -821,7 +822,7 @@ namespace MWMechanics
if (pathgrid == nullptr || pathgrid->mPoints.empty())
return;
const size_t index = PathFinder::getClosestPoint(pathgrid, dest);
const size_t index = Misc::getClosestPoint(*pathgrid, dest);
getPathGridGraph(pathgrid).getNeighbouringPoints(index, points);
}
@ -854,7 +855,7 @@ namespace MWMechanics
const osg::Vec3f npcPos = converter.toLocalVec3(mInitialActorPosition);
// Find closest pathgrid point
size_t closestPointIndex = PathFinder::getClosestPoint(pathgrid, npcPos);
const std::size_t closestPointIndex = Misc::getClosestPoint(*pathgrid, npcPos);
// mAllowedPositions for this actor with pathgrid point indexes based on mDistance
// and if the point is connected to the closest current point

View file

@ -1,14 +1,15 @@
#ifndef GAME_MWMECHANICS_AIWANDER_H
#define GAME_MWMECHANICS_AIWANDER_H
#include "typedaipackage.hpp"
#include <string_view>
#include <vector>
#include "aitemporarybase.hpp"
#include "aitimer.hpp"
#include "pathfinding.hpp"
#include "typedaipackage.hpp"
#include <components/esm3/loadpgrd.hpp>
#include <string_view>
#include <vector>
namespace ESM
{

View file

@ -10,6 +10,7 @@
#include <components/detournavigator/navigatorutils.hpp>
#include <components/misc/coordinateconverter.hpp>
#include <components/misc/math.hpp>
#include <components/misc/pathgridutils.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -38,7 +39,7 @@ namespace
// points to a quadtree may help
for (size_t counter = 0; counter < grid->mPoints.size(); counter++)
{
float potentialDistBetween = MWMechanics::PathFinder::distanceSquared(grid->mPoints[counter], pos);
float potentialDistBetween = Misc::distanceSquared(grid->mPoints[counter], pos);
if (potentialDistBetween < closestDistanceReachable)
{
// found a closer one
@ -197,7 +198,7 @@ namespace MWMechanics
// point right behind the wall that is closer than any pathgrid
// point outside the wall
osg::Vec3f startPointInLocalCoords(converter.toLocalVec3(startPoint));
size_t startNode = getClosestPoint(pathgrid, startPointInLocalCoords);
const size_t startNode = Misc::getClosestPoint(*pathgrid, startPointInLocalCoords);
osg::Vec3f endPointInLocalCoords(converter.toLocalVec3(endPoint));
std::pair<size_t, bool> endNode
@ -206,8 +207,8 @@ namespace MWMechanics
// if it's shorter for actor to travel from start to end, than to travel from either
// start or end to nearest pathgrid point, just travel from start to end.
float startToEndLength2 = (endPointInLocalCoords - startPointInLocalCoords).length2();
float endTolastNodeLength2 = distanceSquared(pathgrid->mPoints[endNode.first], endPointInLocalCoords);
float startTo1stNodeLength2 = distanceSquared(pathgrid->mPoints[startNode], startPointInLocalCoords);
float endTolastNodeLength2 = Misc::distanceSquared(pathgrid->mPoints[endNode.first], endPointInLocalCoords);
float startTo1stNodeLength2 = Misc::distanceSquared(pathgrid->mPoints[startNode], startPointInLocalCoords);
if ((startToEndLength2 < startTo1stNodeLength2) || (startToEndLength2 < endTolastNodeLength2))
{
*out++ = endPoint;

View file

@ -5,12 +5,11 @@
#include <deque>
#include <iterator>
#include <osg/Vec3f>
#include <components/detournavigator/areatype.hpp>
#include <components/detournavigator/flags.hpp>
#include <components/detournavigator/status.hpp>
#include <components/esm/position.hpp>
#include <components/esm3/loadpgrd.hpp>
#include <components/misc/convert.hpp>
namespace MWWorld
{
@ -146,43 +145,6 @@ namespace MWMechanics
mPath.push_back(point);
}
// Slightly cheaper version for comparisons.
// Caller needs to be careful for very short distances (i.e. less than 1)
// or when accumuating the results i.e. (a + b)^2 != a^2 + b^2
//
static float distanceSquared(const ESM::Pathgrid::Point& point, const osg::Vec3f& pos)
{
return (Misc::Convert::makeOsgVec3f(point) - pos).length2();
}
// Return the closest pathgrid point index from the specified position
// coordinates. NOTE: Does not check if there is a sensible way to get there
// (e.g. a cliff in front).
//
// NOTE: pos is expected to be in local coordinates, as is grid->mPoints
//
static size_t getClosestPoint(const ESM::Pathgrid* grid, const osg::Vec3f& pos)
{
assert(grid && !grid->mPoints.empty());
float distanceBetween = distanceSquared(grid->mPoints[0], pos);
size_t closestIndex = 0;
// TODO: if this full scan causes performance problems mapping pathgrid
// points to a quadtree may help
for (size_t counter = 1; counter < grid->mPoints.size(); counter++)
{
float potentialDistBetween = distanceSquared(grid->mPoints[counter], pos);
if (potentialDistBetween < distanceBetween)
{
distanceBetween = potentialDistBetween;
closestIndex = counter;
}
}
return closestIndex;
}
private:
bool mConstructed = false;
std::deque<osg::Vec3f> mPath;

View file

@ -0,0 +1,53 @@
#ifndef OPENMW_COMPONENTS_MISC_PATHGRIDUTILS_H
#define OPENMW_COMPONENTS_MISC_PATHGRIDUTILS_H
#include "convert.hpp"
#include <components/esm3/loadpgrd.hpp>
#include <osg/Vec3f>
#include <stdexcept>
namespace Misc
{
// Slightly cheaper version for comparisons.
// Caller needs to be careful for very short distances (i.e. less than 1)
// or when accumuating the results i.e. (a + b)^2 != a^2 + b^2
//
inline float distanceSquared(const ESM::Pathgrid::Point& point, const osg::Vec3f& pos)
{
return (Misc::Convert::makeOsgVec3f(point) - pos).length2();
}
// Return the closest pathgrid point index from the specified position
// coordinates. NOTE: Does not check if there is a sensible way to get there
// (e.g. a cliff in front).
//
// NOTE: pos is expected to be in local coordinates, as is grid->mPoints
//
inline std::size_t getClosestPoint(const ESM::Pathgrid& grid, const osg::Vec3f& pos)
{
if (grid.mPoints.empty())
throw std::invalid_argument("Pathgrid has no points");
float minDistance = distanceSquared(grid.mPoints[0], pos);
std::size_t closestIndex = 0;
// TODO: if this full scan causes performance problems mapping pathgrid
// points to a quadtree may help
for (std::size_t i = 1; i < grid.mPoints.size(); ++i)
{
const float distance = distanceSquared(grid.mPoints[i], pos);
if (minDistance > distance)
{
minDistance = distance;
closestIndex = i;
}
}
return closestIndex;
}
}
#endif