1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-16 19:29:56 +00:00

Pathfinding Overhaul - Changed the name of checkIfNextPointReached to a more intuitive name considering what it does (checkPathCompleted) and fixed a minor bug in it, modified buildPath() to take one final parameter, a bool which dictates whether or not to always use pathfinding (like AIWander should be doing) or to allow for "shortcuts", modified all ai packages to work with these two changes.

This commit is contained in:
Torben Carrington 2013-05-29 20:05:17 -07:00
parent c080785235
commit 73a9671742
5 changed files with 24 additions and 16 deletions

View file

@ -129,10 +129,10 @@ bool MWMechanics::AiEscort::execute (const MWWorld::Ptr& actor)
start.mY = pos.pos[1];
start.mZ = pos.pos[2];
mPathFinder.buildPath(start,dest,pathgrid,xCell,yCell);
mPathFinder.buildPath(start, dest, pathgrid, xCell, yCell, 1);
}
if(mPathFinder.checkIfNextPointReached(pos.pos[0],pos.pos[1],pos.pos[2]))
if(mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1],pos.pos[2]))
{
MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0;
return true;

View file

@ -78,10 +78,10 @@ bool MWMechanics::AiTravel::execute (const MWWorld::Ptr& actor)
start.mY = pos.pos[1];
start.mZ = pos.pos[2];
mPathFinder.buildPath(start,dest,pathgrid,xCell,yCell);
mPathFinder.buildPath(start, dest, pathgrid, xCell, yCell, 1);
}
if(mPathFinder.checkIfNextPointReached(pos.pos[0],pos.pos[1],pos.pos[2]))
if(mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1],pos.pos[2]))
{
MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0;
return true;

View file

@ -235,7 +235,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor)
start.mY = pos.pos[1];
start.mZ = pos.pos[2];
mPathFinder.buildPath(start,dest,mPathgrid,mXCell,mYCell);
mPathFinder.buildPath(start, dest, mPathgrid, mXCell, mYCell, 0);
mWalking = true;
}
}
@ -254,7 +254,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor)
actorPos[1] = actorPos[1] - mYCell;
float distance = actorPos.squaredDistance(destNodePos);
if(distance < 1200 || mPathFinder.checkIfNextPointReached(pos.pos[0],pos.pos[1],pos.pos[2]))
if(distance < 1200 || mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1],pos.pos[2]))
{
stopWalking(actor);
mMoveNow = false;

View file

@ -148,11 +148,16 @@ namespace MWMechanics
}
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, bool allowShortcuts)
{
if(allowShortcuts)
{
if(MWBase::Environment::get().getWorld()->castRay(startPoint.mX, startPoint.mY, startPoint.mZ, endPoint.mX, endPoint.mY,
endPoint.mZ))
allowShortcuts = false;
}
//first check if there is an obstacle
if(MWBase::Environment::get().getWorld()->castRay(startPoint.mX, startPoint.mY, startPoint.mZ,
endPoint.mX, endPoint.mY, endPoint.mZ) )
if(!allowShortcuts)
{
int startNode = getClosestPoint(pathGrid, startPoint.mX - xCell, startPoint.mY - yCell,startPoint.mZ);
int endNode = getClosestPoint(pathGrid, endPoint.mX - xCell, endPoint.mY - yCell, endPoint.mZ);
@ -175,14 +180,14 @@ namespace MWMechanics
return 0;
ESM::Pathgrid::Point nextPoint = *mPath.begin();
float dX = nextPoint.mX - x;
float dY = nextPoint.mY - y;
float h = sqrt(dX * dX + dY * dY);
float directionX = nextPoint.mX - x;
float directionY = nextPoint.mY - y;
float directionResult = sqrt(directionX * directionX + directionY * directionY);
return Ogre::Radian(acos(dY / h) * sgn(asin(dX / h))).valueDegrees();
return Ogre::Radian(acos(directionY / directionResult) * sgn(asin(directionX / directionResult))).valueDegrees();
}
bool PathFinder::checkIfNextPointReached(float x, float y, float z)
bool PathFinder::checkPathCompleted(float x, float y, float z)
{
if(mPath.empty())
return true;
@ -192,7 +197,10 @@ namespace MWMechanics
{
mPath.pop_front();
if(mPath.empty())
{
mIsPathConstructed = false;
return true;
}
}
return false;

View file

@ -13,9 +13,9 @@ namespace MWMechanics
void clearPath();
void buildPath(ESM::Pathgrid::Point startPoint, ESM::Pathgrid::Point endPoint,
const ESM::Pathgrid* pathGrid, float xCell = 0, float yCell = 0);
const ESM::Pathgrid* pathGrid, float xCell = 0, float yCell = 0, bool allowShortcuts = 1);
bool checkIfNextPointReached(float x, float y, float z);
bool checkPathCompleted(float x, float y, float z);
///< \Returns true if the last point of the path has been reached.
float getZAngleToNext(float x, float y);