mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 09:35:28 +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:
parent
7b465ae4f1
commit
c080785235
@ -151,7 +151,7 @@ bool MWMechanics::AiEscort::execute (const MWWorld::Ptr& actor)
|
|||||||
|
|
||||||
if(distanceBetweenResult <= mMaxDist * mMaxDist)
|
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);
|
MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false);
|
||||||
MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1;
|
MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1;
|
||||||
mMaxDist = 470;
|
mMaxDist = 470;
|
||||||
|
@ -87,7 +87,7 @@ bool MWMechanics::AiTravel::execute (const MWWorld::Ptr& actor)
|
|||||||
return true;
|
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);
|
MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false);
|
||||||
MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1;
|
MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1;
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor)
|
|||||||
{
|
{
|
||||||
if(!mRepeat)
|
if(!mRepeat)
|
||||||
{
|
{
|
||||||
stopWalking(actor, mPathFinder);
|
stopWalking(actor);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -74,7 +74,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor)
|
|||||||
{
|
{
|
||||||
if(!mRepeat)
|
if(!mRepeat)
|
||||||
{
|
{
|
||||||
stopWalking(actor, mPathFinder);
|
stopWalking(actor);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -149,7 +149,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor)
|
|||||||
// FIXME: This *should* pause the AiWander package instead of terminating it.
|
// 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))
|
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;
|
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.
|
// 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))
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -242,7 +242,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor)
|
|||||||
|
|
||||||
if(mWalking)
|
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);
|
MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false);
|
||||||
MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1;
|
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]))
|
if(distance < 1200 || mPathFinder.checkIfNextPointReached(pos.pos[0],pos.pos[1],pos.pos[2]))
|
||||||
{
|
{
|
||||||
stopWalking(actor, mPathFinder);
|
stopWalking(actor);
|
||||||
mMoveNow = false;
|
mMoveNow = false;
|
||||||
mWalking = false;
|
mWalking = false;
|
||||||
mChooseAction = true;
|
mChooseAction = true;
|
||||||
@ -272,10 +272,9 @@ int MWMechanics::AiWander::getTypeId() const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWMechanics::AiWander::stopWalking(const MWWorld::Ptr& actor, PathFinder& path)
|
void MWMechanics::AiWander::stopWalking(const MWWorld::Ptr& actor)
|
||||||
{
|
{
|
||||||
PathFinder pathClearer;
|
mPathFinder.clearPath();
|
||||||
path = pathClearer;
|
|
||||||
MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0;
|
MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ namespace MWMechanics
|
|||||||
///< 0: Wander
|
///< 0: Wander
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void stopWalking(const MWWorld::Ptr& actor, PathFinder& path);
|
void stopWalking(const MWWorld::Ptr& actor);
|
||||||
void playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect);
|
void playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect);
|
||||||
bool checkIdle(const MWWorld::Ptr& actor, unsigned short idleSelect);
|
bool checkIdle(const MWWorld::Ptr& actor, unsigned short idleSelect);
|
||||||
|
|
||||||
|
@ -31,17 +31,26 @@ namespace
|
|||||||
|
|
||||||
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));
|
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)
|
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)
|
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)
|
static float sgn(float a)
|
||||||
@ -75,18 +84,18 @@ namespace
|
|||||||
{
|
{
|
||||||
PathGridGraph graph;
|
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);
|
PointID pID = boost::add_vertex(graph);
|
||||||
graph[pID].mX = pathgrid->mPoints[i].mX + xCell;
|
graph[pID].mX = pathgrid->mPoints[counter].mX + xCell;
|
||||||
graph[pID].mY = pathgrid->mPoints[i].mY + yCell;
|
graph[pID].mY = pathgrid->mPoints[counter].mY + yCell;
|
||||||
graph[pID].mZ = pathgrid->mPoints[i].mZ;
|
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 u = pathgrid->mEdges[counterTwo].mV0;
|
||||||
PointID v = pathgrid->mEdges[i].mV1;
|
PointID v = pathgrid->mEdges[counterTwo].mV1;
|
||||||
|
|
||||||
PointConnectionID edge;
|
PointConnectionID edge;
|
||||||
bool done;
|
bool done;
|
||||||
@ -145,13 +154,13 @@ namespace MWMechanics
|
|||||||
if(MWBase::Environment::get().getWorld()->castRay(startPoint.mX, startPoint.mY, startPoint.mZ,
|
if(MWBase::Environment::get().getWorld()->castRay(startPoint.mX, startPoint.mY, startPoint.mZ,
|
||||||
endPoint.mX, endPoint.mY, endPoint.mZ) )
|
endPoint.mX, endPoint.mY, endPoint.mZ) )
|
||||||
{
|
{
|
||||||
int start = getClosestPoint(pathGrid, startPoint.mX - xCell, startPoint.mY - yCell,startPoint.mZ);
|
int startNode = getClosestPoint(pathGrid, startPoint.mX - xCell, startPoint.mY - yCell,startPoint.mZ);
|
||||||
int end = getClosestPoint(pathGrid, endPoint.mX - xCell, endPoint.mY - yCell, endPoint.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);
|
PathGridGraph graph = buildGraph(pathGrid, xCell, yCell);
|
||||||
mPath = findPath(start, end, graph);
|
mPath = findPath(startNode, endNode, graph);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,10 +168,11 @@ namespace MWMechanics
|
|||||||
mIsPathConstructed = true;
|
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())
|
if(mPath.empty())
|
||||||
return 0; // shouldn't happen!
|
return 0;
|
||||||
|
|
||||||
ESM::Pathgrid::Point nextPoint = *mPath.begin();
|
ESM::Pathgrid::Point nextPoint = *mPath.begin();
|
||||||
float dX = nextPoint.mX - x;
|
float dX = nextPoint.mX - x;
|
||||||
|
@ -12,12 +12,12 @@ namespace MWMechanics
|
|||||||
PathFinder();
|
PathFinder();
|
||||||
|
|
||||||
void clearPath();
|
void clearPath();
|
||||||
void buildPath(ESM::Pathgrid::Point startPoint,ESM::Pathgrid::Point endPoint,
|
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 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.
|
///< \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();
|
std::list<ESM::Pathgrid::Point> getPath();
|
||||||
bool isPathConstructed();
|
bool isPathConstructed();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user