1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-25 06:35:30 +00:00

Pathfinding Overhaul - Finished cleaning, removed unnecessary parameter in one function, fixed use of the function in ai packages and added use of clearPath() function in aiwander, fixed algorithms and got rid of excess subtractions in getDistance functions (thanks to Chris!).

This commit is contained in:
Torben Carrington 2013-05-29 19:26:45 -07:00
parent 7b465ae4f1
commit c080785235
6 changed files with 41 additions and 32 deletions

View File

@ -151,7 +151,7 @@ bool MWMechanics::AiEscort::execute (const MWWorld::Ptr& actor)
if(distanceBetweenResult <= mMaxDist * mMaxDist)
{
float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1],pos.pos[2]);
float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1]);
MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false);
MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1;
mMaxDist = 470;

View File

@ -87,7 +87,7 @@ bool MWMechanics::AiTravel::execute (const MWWorld::Ptr& actor)
return true;
}
float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1],pos.pos[2]);
float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1]);
MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false);
MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1;

View File

@ -64,7 +64,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor)
{
if(!mRepeat)
{
stopWalking(actor, mPathFinder);
stopWalking(actor);
return true;
}
else
@ -74,7 +74,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor)
{
if(!mRepeat)
{
stopWalking(actor, mPathFinder);
stopWalking(actor);
return true;
}
else
@ -149,7 +149,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor)
// FIXME: This *should* pause the AiWander package instead of terminating it.
if(sideX*(pos.pos[0] - actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE) > sideX * (ESM::Land::REAL_SIZE / 2.0 - 200))
{
MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0;
stopWalking(actor);
return true;
}
}
@ -161,7 +161,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor)
// FIXME: This *should* pause the AiWander package instead of terminating it.
if(sideY*(pos.pos[1] - actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE) > sideY * (ESM::Land::REAL_SIZE / 2.0 - 200))
{
MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0;
stopWalking(actor);
return true;
}
}
@ -242,7 +242,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor)
if(mWalking)
{
float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1],pos.pos[2]);
float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1]);
MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false);
MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1;
@ -256,7 +256,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor)
if(distance < 1200 || mPathFinder.checkIfNextPointReached(pos.pos[0],pos.pos[1],pos.pos[2]))
{
stopWalking(actor, mPathFinder);
stopWalking(actor);
mMoveNow = false;
mWalking = false;
mChooseAction = true;
@ -272,10 +272,9 @@ int MWMechanics::AiWander::getTypeId() const
return 0;
}
void MWMechanics::AiWander::stopWalking(const MWWorld::Ptr& actor, PathFinder& path)
void MWMechanics::AiWander::stopWalking(const MWWorld::Ptr& actor)
{
PathFinder pathClearer;
path = pathClearer;
mPathFinder.clearPath();
MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0;
}

View File

@ -22,7 +22,7 @@ namespace MWMechanics
///< 0: Wander
private:
void stopWalking(const MWWorld::Ptr& actor, PathFinder& path);
void stopWalking(const MWWorld::Ptr& actor);
void playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect);
bool checkIdle(const MWWorld::Ptr& actor, unsigned short idleSelect);

View File

@ -31,17 +31,26 @@ namespace
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));
x -= point.mX;
y -= point.mY;
z -= point.mZ;
return sqrt(x * x + y * y + 0.1 * z * 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));
x -= point.mX;
y -= point.mY;
z -= point.mZ;
return sqrt(x * x + y * y + z * z);
}
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));
float x = a.mX - b.mX;
float y = a.mY - b.mY;
float z = a.mZ - b.mZ;
return sqrt(x * x + y * y + z * z);
}
static float sgn(float a)
@ -75,18 +84,18 @@ namespace
{
PathGridGraph graph;
for(unsigned int i = 0; i < pathgrid->mPoints.size(); ++i)
for(unsigned int counter = 0; counter < pathgrid->mPoints.size(); counter++)
{
PointID pID = boost::add_vertex(graph);
graph[pID].mX = pathgrid->mPoints[i].mX + xCell;
graph[pID].mY = pathgrid->mPoints[i].mY + yCell;
graph[pID].mZ = pathgrid->mPoints[i].mZ;
graph[pID].mX = pathgrid->mPoints[counter].mX + xCell;
graph[pID].mY = pathgrid->mPoints[counter].mY + yCell;
graph[pID].mZ = pathgrid->mPoints[counter].mZ;
}
for(unsigned int i = 0;i<pathgrid->mEdges.size();++i)
for(unsigned int counterTwo = 0; counterTwo < pathgrid->mEdges.size(); counterTwo++)
{
PointID u = pathgrid->mEdges[i].mV0;
PointID v = pathgrid->mEdges[i].mV1;
PointID u = pathgrid->mEdges[counterTwo].mV0;
PointID v = pathgrid->mEdges[counterTwo].mV1;
PointConnectionID edge;
bool done;
@ -145,13 +154,13 @@ namespace MWMechanics
if(MWBase::Environment::get().getWorld()->castRay(startPoint.mX, startPoint.mY, startPoint.mZ,
endPoint.mX, endPoint.mY, endPoint.mZ) )
{
int start = getClosestPoint(pathGrid, startPoint.mX - xCell, startPoint.mY - yCell,startPoint.mZ);
int end = getClosestPoint(pathGrid, endPoint.mX - xCell, endPoint.mY - yCell, endPoint.mZ);
int startNode = getClosestPoint(pathGrid, startPoint.mX - xCell, startPoint.mY - yCell,startPoint.mZ);
int endNode = getClosestPoint(pathGrid, endPoint.mX - xCell, endPoint.mY - yCell, endPoint.mZ);
if(start != -1 && end != -1)
if(startNode != -1 && endNode != -1)
{
PathGridGraph graph = buildGraph(pathGrid, xCell, yCell);
mPath = findPath(start, end, graph);
mPath = findPath(startNode, endNode, graph);
}
}
@ -159,10 +168,11 @@ namespace MWMechanics
mIsPathConstructed = true;
}
float PathFinder::getZAngleToNext(float x, float y, float z)
float PathFinder::getZAngleToNext(float x, float y)
{
// This if should never be true:
if(mPath.empty())
return 0; // shouldn't happen!
return 0;
ESM::Pathgrid::Point nextPoint = *mPath.begin();
float dX = nextPoint.mX - x;

View File

@ -12,12 +12,12 @@ namespace MWMechanics
PathFinder();
void clearPath();
void buildPath(ESM::Pathgrid::Point startPoint,ESM::Pathgrid::Point endPoint,
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);
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);
std::list<ESM::Pathgrid::Point> getPath();
bool isPathConstructed();