diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index a769d85cdd..7f6003d5b2 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -1,13 +1,11 @@ #include "aicombat.hpp" -#include -#include - -#include - -#include - #include +#include +#include +#include +#include +#include #include #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)) diff --git a/apps/openmw/mwmechanics/aicombat.hpp b/apps/openmw/mwmechanics/aicombat.hpp index d5a9c3464c..42baaf6349 100644 --- a/apps/openmw/mwmechanics/aicombat.hpp +++ b/apps/openmw/mwmechanics/aicombat.hpp @@ -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 namespace ESM { diff --git a/apps/openmw/mwmechanics/aipackage.hpp b/apps/openmw/mwmechanics/aipackage.hpp index edb62c97c4..42aa62ffe3 100644 --- a/apps/openmw/mwmechanics/aipackage.hpp +++ b/apps/openmw/mwmechanics/aipackage.hpp @@ -16,6 +16,8 @@ namespace ESM { struct Cell; + struct Pathgrid; + namespace AiSequence { struct AiSequence; diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index dfa0bc41ac..7ebf37158b 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #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 diff --git a/apps/openmw/mwmechanics/aiwander.hpp b/apps/openmw/mwmechanics/aiwander.hpp index 0518015936..3e0b704524 100644 --- a/apps/openmw/mwmechanics/aiwander.hpp +++ b/apps/openmw/mwmechanics/aiwander.hpp @@ -1,14 +1,15 @@ #ifndef GAME_MWMECHANICS_AIWANDER_H #define GAME_MWMECHANICS_AIWANDER_H -#include "typedaipackage.hpp" - -#include -#include - #include "aitemporarybase.hpp" #include "aitimer.hpp" #include "pathfinding.hpp" +#include "typedaipackage.hpp" + +#include + +#include +#include namespace ESM { diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index dcad29c907..d8b17529ab 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #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 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; diff --git a/apps/openmw/mwmechanics/pathfinding.hpp b/apps/openmw/mwmechanics/pathfinding.hpp index 20ba85cc96..45827a25df 100644 --- a/apps/openmw/mwmechanics/pathfinding.hpp +++ b/apps/openmw/mwmechanics/pathfinding.hpp @@ -5,12 +5,11 @@ #include #include +#include + #include #include #include -#include -#include -#include 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 mPath; diff --git a/components/misc/pathgridutils.hpp b/components/misc/pathgridutils.hpp new file mode 100644 index 0000000000..5ca58f4d08 --- /dev/null +++ b/components/misc/pathgridutils.hpp @@ -0,0 +1,53 @@ +#ifndef OPENMW_COMPONENTS_MISC_PATHGRIDUTILS_H +#define OPENMW_COMPONENTS_MISC_PATHGRIDUTILS_H + +#include "convert.hpp" + +#include + +#include + +#include + +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