mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-03 23:56:43 +00:00 
			
		
		
		
	Pathfinding Overhaul - Cleanup, removed unnecessary include, fixed spacing, added a function for clearing a path, overall preperation to begin working on fixing pathfinding.
This commit is contained in:
		
							parent
							
								
									dc17fa1636
								
							
						
					
					
						commit
						4838678944
					
				
					 2 changed files with 87 additions and 78 deletions
				
			
		| 
						 | 
					@ -3,46 +3,48 @@
 | 
				
			||||||
#include "../mwbase/world.hpp"
 | 
					#include "../mwbase/world.hpp"
 | 
				
			||||||
#include "../mwbase/environment.hpp"
 | 
					#include "../mwbase/environment.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "OgreMath.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <boost/graph/dijkstra_shortest_paths.hpp>
 | 
					#include <boost/graph/dijkstra_shortest_paths.hpp>
 | 
				
			||||||
#include <boost/graph/adjacency_list.hpp>
 | 
					#include <boost/graph/adjacency_list.hpp>
 | 
				
			||||||
#include "boost/tuple/tuple.hpp"
 | 
					 | 
				
			||||||
#include "OgreMath.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace
 | 
					namespace
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	//helpers functions
 | 
					//helpers functions
 | 
				
			||||||
    float distanceZCorrected(ESM::Pathgrid::Point point,float x,float y,float z)
 | 
					    float distanceZCorrected(ESM::Pathgrid::Point point,float x,float y,float z)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return sqrt((point.mX - x)*(point.mX - x)+(point.mY - y)*(point.mY - y)+0.1*(point.mZ - z)*(point.mZ - z));
 | 
					        return sqrt((point.mX - x) * (point.mX - x) + (point.mY - y) * (point.mY - y) + 0.1 * (point.mZ - z) * (point.mZ - z));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    float distance(ESM::Pathgrid::Point point,float x,float y,float z)
 | 
					    float distance(ESM::Pathgrid::Point point,float x,float y,float z)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return sqrt((point.mX - x)*(point.mX - x)+(point.mY - y)*(point.mY - y)+(point.mZ - z)*(point.mZ - z));
 | 
					        return sqrt((point.mX - x) * (point.mX - x) + (point.mY - y) * (point.mY - y) + (point.mZ - z) * (point.mZ - z));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    float distance(ESM::Pathgrid::Point a,ESM::Pathgrid::Point b)
 | 
					    float distance(ESM::Pathgrid::Point a,ESM::Pathgrid::Point b)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return sqrt(float(a.mX - b.mX)*(a.mX - b.mX)+(a.mY - b.mY)*(a.mY - b.mY)+(a.mZ - b.mZ)*(a.mZ - b.mZ));
 | 
					        return sqrt(float(a.mX - b.mX) * (a.mX - b.mX) + (a.mY - b.mY) * (a.mY - b.mY) + (a.mZ - b.mZ) * (a.mZ - b.mZ));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static float sgn(float a)
 | 
					    static float sgn(float a)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if(a>0) return 1.;
 | 
					        if(a > 0) return 1.0;
 | 
				
			||||||
        else return -1.;
 | 
					        else return -1.0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int getClosestPoint(const ESM::Pathgrid* grid,float x,float y,float z)
 | 
					    int getClosestPoint(const ESM::Pathgrid* grid,float x,float y,float z)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if(!grid) return -1;
 | 
					        if(!grid)
 | 
				
			||||||
        if(grid->mPoints.empty()) return -1;
 | 
					            return -1;
 | 
				
			||||||
 | 
					        if(grid->mPoints.empty())
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        float m = distance(grid->mPoints[0],x,y,z);
 | 
					        float m = distance(grid->mPoints[0],x,y,z);
 | 
				
			||||||
        int i0 = 0;
 | 
					        int i0 = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for(unsigned int i=1; i<grid->mPoints.size();++i)
 | 
					        for(unsigned int i = 1; i < grid->mPoints.size(); ++i)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if(distance(grid->mPoints[i],x,y,z)<m)
 | 
					            if(distance(grid->mPoints[i],x,y,z) < m)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                m = distance(grid->mPoints[i],x,y,z);
 | 
					                m = distance(grid->mPoints[i],x,y,z);
 | 
				
			||||||
                i0 = i;
 | 
					                i0 = i;
 | 
				
			||||||
| 
						 | 
					@ -55,64 +57,64 @@ namespace
 | 
				
			||||||
        boost::property<boost::vertex_index_t,int,ESM::Pathgrid::Point>,boost::property<boost::edge_weight_t,float> > PathGridGraph;
 | 
					        boost::property<boost::vertex_index_t,int,ESM::Pathgrid::Point>,boost::property<boost::edge_weight_t,float> > PathGridGraph;
 | 
				
			||||||
    typedef boost::property_map<PathGridGraph, boost::edge_weight_t>::type WeightMap;
 | 
					    typedef boost::property_map<PathGridGraph, boost::edge_weight_t>::type WeightMap;
 | 
				
			||||||
    typedef PathGridGraph::vertex_descriptor PointID;
 | 
					    typedef PathGridGraph::vertex_descriptor PointID;
 | 
				
			||||||
    typedef PathGridGraph::edge_descriptor   PointConnectionID;
 | 
					    typedef PathGridGraph::edge_descriptor PointConnectionID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct found_path {};
 | 
					    struct found_path {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*class goalVisited : public boost::default_astar_visitor
 | 
					    /*class goalVisited : public boost::default_astar_visitor
 | 
				
			||||||
    {
 | 
					{
 | 
				
			||||||
    public:
 | 
					public:
 | 
				
			||||||
        goalVisited(PointID goal) : mGoal(goal) {}
 | 
					goalVisited(PointID goal) : mGoal(goal) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void examine_vertex(PointID u, const PathGridGraph g)
 | 
					void examine_vertex(PointID u, const PathGridGraph g)
 | 
				
			||||||
        {
 | 
					{
 | 
				
			||||||
            if(u == mGoal)
 | 
					if(u == mGoal)
 | 
				
			||||||
                throw found_path();
 | 
					throw found_path();
 | 
				
			||||||
        }
 | 
					}
 | 
				
			||||||
    private:
 | 
					private:
 | 
				
			||||||
        PointID mGoal;
 | 
					PointID mGoal;
 | 
				
			||||||
    };
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class DistanceHeuristic : public boost::atasr_heuristic <PathGridGraph, float>
 | 
					class DistanceHeuristic : public boost::atasr_heuristic <PathGridGraph, float>
 | 
				
			||||||
    {
 | 
					{
 | 
				
			||||||
    public:
 | 
					public:
 | 
				
			||||||
        DistanceHeuristic(const PathGridGraph & l, PointID goal)
 | 
					DistanceHeuristic(const PathGridGraph & l, PointID goal)
 | 
				
			||||||
            : mGraph(l), mGoal(goal) {}
 | 
					: mGraph(l), mGoal(goal) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        float operator()(PointID u)
 | 
					float operator()(PointID u)
 | 
				
			||||||
        {
 | 
					{
 | 
				
			||||||
            const ESM::Pathgrid::Point & U = mGraph[u];
 | 
					const ESM::Pathgrid::Point & U = mGraph[u];
 | 
				
			||||||
            const ESM::Pathgrid::Point & V = mGraph[mGoal];
 | 
					const ESM::Pathgrid::Point & V = mGraph[mGoal];
 | 
				
			||||||
            float dx = U.mX - V.mX;
 | 
					float dx = U.mX - V.mX;
 | 
				
			||||||
            float dy = U.mY - V.mY;
 | 
					float dy = U.mY - V.mY;
 | 
				
			||||||
            float dz = U.mZ - V.mZ;
 | 
					float dz = U.mZ - V.mZ;
 | 
				
			||||||
            return sqrt(dx * dx + dy * dy + dz * dz);
 | 
					return sqrt(dx * dx + dy * dy + dz * dz);
 | 
				
			||||||
        }
 | 
					}
 | 
				
			||||||
    private:
 | 
					private:
 | 
				
			||||||
        const PathGridGraph & mGraph;
 | 
					const PathGridGraph & mGraph;
 | 
				
			||||||
        PointID mGoal;
 | 
					PointID mGoal;
 | 
				
			||||||
    };*/
 | 
					};*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class goalVisited : public boost::default_dijkstra_visitor
 | 
					class goalVisited : public boost::default_dijkstra_visitor
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	public:
 | 
					public:
 | 
				
			||||||
		goalVisited(PointID goal) : mGoal(goal) {}
 | 
					goalVisited(PointID goal) : mGoal(goal) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void examine_vertex(PointID u, const PathGridGraph g)
 | 
					void examine_vertex(PointID u, const PathGridGraph g)
 | 
				
			||||||
		{
 | 
					{
 | 
				
			||||||
			if(u == mGoal)
 | 
					if(u == mGoal)
 | 
				
			||||||
				throw found_path();
 | 
					throw found_path();
 | 
				
			||||||
		}
 | 
					}
 | 
				
			||||||
	private:
 | 
					private:
 | 
				
			||||||
		PointID mGoal;
 | 
					PointID mGoal;
 | 
				
			||||||
	};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PathGridGraph buildGraph(const ESM::Pathgrid* pathgrid,float xCell = 0,float yCell = 0)
 | 
					    PathGridGraph buildGraph(const ESM::Pathgrid* pathgrid,float xCell = 0,float yCell = 0)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        PathGridGraph graph;
 | 
					        PathGridGraph graph;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for(unsigned int i = 0;i<pathgrid->mPoints.size();++i)
 | 
					        for(unsigned int i = 0; i < pathgrid->mPoints.size(); ++i)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            PointID pID = boost::add_vertex(graph);
 | 
					            PointID pID = boost::add_vertex(graph);
 | 
				
			||||||
            graph[pID].mX = pathgrid->mPoints[i].mX + xCell;
 | 
					            graph[pID].mX = pathgrid->mPoints[i].mX + xCell;
 | 
				
			||||||
| 
						 | 
					@ -130,7 +132,6 @@ namespace
 | 
				
			||||||
            boost::tie(edge,done) = boost::add_edge(u,v,graph);
 | 
					            boost::tie(edge,done) = boost::add_edge(u,v,graph);
 | 
				
			||||||
            WeightMap weightmap = boost::get(boost::edge_weight, graph);
 | 
					            WeightMap weightmap = boost::get(boost::edge_weight, graph);
 | 
				
			||||||
            weightmap[edge] = distance(graph[u],graph[v]);
 | 
					            weightmap[edge] = distance(graph[u],graph[v]);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return graph;
 | 
					        return graph;
 | 
				
			||||||
| 
						 | 
					@ -147,10 +148,10 @@ namespace
 | 
				
			||||||
                graph,
 | 
					                graph,
 | 
				
			||||||
                start,
 | 
					                start,
 | 
				
			||||||
                boost::predecessor_map(&p[0]).distance_map(&d[0]).visitor(goalVisited(end))//.weight_map(boost::get(&Edge::distance, graph))
 | 
					                boost::predecessor_map(&p[0]).distance_map(&d[0]).visitor(goalVisited(end))//.weight_map(boost::get(&Edge::distance, graph))
 | 
				
			||||||
				);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        } catch(found_path fg) {
 | 
					        } catch(found_path fg) {
 | 
				
			||||||
            for(PointID v = end;; v = p[v]) {
 | 
					            for(PointID v = end; ; v = p[v]) {
 | 
				
			||||||
                shortest_path.push_front(graph[v]);
 | 
					                shortest_path.push_front(graph[v]);
 | 
				
			||||||
                if(p[v] == v)
 | 
					                if(p[v] == v)
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
| 
						 | 
					@ -170,6 +171,13 @@ namespace MWMechanics
 | 
				
			||||||
        mIsPathConstructed = false;
 | 
					        mIsPathConstructed = false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void PathFinder::clearPath()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if(!mPath.empty())
 | 
				
			||||||
 | 
					            mPath.clear();
 | 
				
			||||||
 | 
					        mIsPathConstructed = false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void PathFinder::buildPath(ESM::Pathgrid::Point startPoint,ESM::Pathgrid::Point endPoint,
 | 
					    void PathFinder::buildPath(ESM::Pathgrid::Point startPoint,ESM::Pathgrid::Point endPoint,
 | 
				
			||||||
        const ESM::Pathgrid* pathGrid,float xCell,float yCell)
 | 
					        const ESM::Pathgrid* pathGrid,float xCell,float yCell)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
| 
						 | 
					@ -193,9 +201,8 @@ namespace MWMechanics
 | 
				
			||||||
    float PathFinder::getZAngleToNext(float x,float y,float z)
 | 
					    float PathFinder::getZAngleToNext(float x,float y,float z)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if(mPath.empty())
 | 
					        if(mPath.empty())
 | 
				
			||||||
        {
 | 
					            return 0; /// shouldn't happen!
 | 
				
			||||||
            return 0;/// shouldn't happen!
 | 
					
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        ESM::Pathgrid::Point nextPoint = *mPath.begin();
 | 
					        ESM::Pathgrid::Point nextPoint = *mPath.begin();
 | 
				
			||||||
        float dX = nextPoint.mX - x;
 | 
					        float dX = nextPoint.mX - x;
 | 
				
			||||||
        float dY = nextPoint.mY - y;
 | 
					        float dY = nextPoint.mY - y;
 | 
				
			||||||
| 
						 | 
					@ -206,17 +213,16 @@ namespace MWMechanics
 | 
				
			||||||
    bool PathFinder::checkIfNextPointReached(float x,float y,float z)
 | 
					    bool PathFinder::checkIfNextPointReached(float x,float y,float z)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if(mPath.empty())
 | 
					        if(mPath.empty())
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					
 | 
				
			||||||
        ESM::Pathgrid::Point nextPoint = *mPath.begin();
 | 
					        ESM::Pathgrid::Point nextPoint = *mPath.begin();
 | 
				
			||||||
        if(distanceZCorrected(nextPoint,x,y,z) < 20)
 | 
					        if(distanceZCorrected(nextPoint,x,y,z) < 20)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            mPath.pop_front();
 | 
					            mPath.pop_front();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(mPath.empty())
 | 
					            if(mPath.empty())
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                return true;
 | 
					                return true;
 | 
				
			||||||
            }
 | 
					
 | 
				
			||||||
            nextPoint = *mPath.begin();
 | 
					            nextPoint = *mPath.begin();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
| 
						 | 
					@ -226,8 +232,10 @@ namespace MWMechanics
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return mPath;
 | 
					        return mPath;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool PathFinder::isPathConstructed()
 | 
					    bool PathFinder::isPathConstructed()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return mIsPathConstructed;
 | 
					        return mIsPathConstructed;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,22 +8,23 @@ namespace MWMechanics
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    class PathFinder
 | 
					    class PathFinder
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    public:
 | 
					        public:
 | 
				
			||||||
        PathFinder();
 | 
					            PathFinder();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void buildPath(ESM::Pathgrid::Point startPoint,ESM::Pathgrid::Point endPoint,
 | 
					            void clearPath();
 | 
				
			||||||
            const ESM::Pathgrid* pathGrid,float xCell = 0,float yCell = 0);
 | 
					            void buildPath(ESM::Pathgrid::Point startPoint,ESM::Pathgrid::Point endPoint,
 | 
				
			||||||
 | 
					                const ESM::Pathgrid* pathGrid,float xCell = 0,float yCell = 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bool checkIfNextPointReached(float x,float y,float z);//returns true if the last point of the path has been reached.
 | 
					            bool checkIfNextPointReached(float x,float y,float z);//returns true if the last point of the path has been reached.
 | 
				
			||||||
        float getZAngleToNext(float x,float y,float z);
 | 
					            float getZAngleToNext(float x,float y,float z);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::list<ESM::Pathgrid::Point> getPath();
 | 
					            std::list<ESM::Pathgrid::Point> getPath();
 | 
				
			||||||
        bool isPathConstructed();
 | 
					            bool isPathConstructed();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private:
 | 
					        private:
 | 
				
			||||||
        std::list<ESM::Pathgrid::Point> mPath;
 | 
					            std::list<ESM::Pathgrid::Point> mPath;
 | 
				
			||||||
        bool mIsPathConstructed;
 | 
					            bool mIsPathConstructed;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue