mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-21 09:39:56 +00:00
Use worldspace coords in AiWanderStorage
This commit is contained in:
parent
a9dbb023d7
commit
d40a9ec5bc
@ -503,11 +503,9 @@ namespace MWMechanics
|
||||
bool AiWander::isNearAllowedNode(const MWWorld::Ptr& actor, const AiWanderStorage& storage, float distance) const
|
||||
{
|
||||
const osg::Vec3f actorPos = actor.getRefData().getPosition().asVec3();
|
||||
auto cell = actor.getCell()->getCell();
|
||||
for (const ESM::Pathgrid::Point& node : storage.mAllowedNodes)
|
||||
{
|
||||
osg::Vec3f point(node.mX, node.mY, node.mZ);
|
||||
Misc::CoordinateConverter(cell).toWorld(point);
|
||||
if ((actorPos - point).length2() < distance * distance)
|
||||
return true;
|
||||
}
|
||||
@ -601,11 +599,8 @@ namespace MWMechanics
|
||||
{
|
||||
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
|
||||
unsigned int randNode = Misc::Rng::rollDice(storage.mAllowedNodes.size(), prng);
|
||||
ESM::Pathgrid::Point dest(storage.mAllowedNodes[randNode]);
|
||||
const ESM::Pathgrid::Point& dest = storage.mAllowedNodes[randNode];
|
||||
|
||||
ToWorldCoordinates(dest, actor.getCell()->getCell());
|
||||
|
||||
// actor position is already in world coordinates
|
||||
const osg::Vec3f start = actorPos.asVec3();
|
||||
|
||||
// don't take shortcuts for wandering
|
||||
@ -635,11 +630,6 @@ namespace MWMechanics
|
||||
storage.mAllowedNodes.erase(storage.mAllowedNodes.begin() + randNode);
|
||||
}
|
||||
|
||||
void AiWander::ToWorldCoordinates(ESM::Pathgrid::Point& point, const ESM::Cell* cell)
|
||||
{
|
||||
Misc::CoordinateConverter(cell).toWorld(point);
|
||||
}
|
||||
|
||||
void AiWander::trimAllowedNodes(std::vector<ESM::Pathgrid::Point>& nodes, const PathFinder& pathfinder)
|
||||
{
|
||||
// TODO: how to add these back in once the door opens?
|
||||
@ -739,9 +729,9 @@ namespace MWMechanics
|
||||
|
||||
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
|
||||
int index = Misc::Rng::rollDice(storage.mAllowedNodes.size(), prng);
|
||||
ESM::Pathgrid::Point dest = storage.mAllowedNodes[index];
|
||||
ESM::Pathgrid::Point worldDest = dest;
|
||||
ToWorldCoordinates(worldDest, actor.getCell()->getCell());
|
||||
ESM::Pathgrid::Point worldDest = storage.mAllowedNodes[index];
|
||||
auto converter = Misc::CoordinateConverter(actor.getCell()->getCell());
|
||||
ESM::Pathgrid::Point dest = converter.toLocalPoint(worldDest);
|
||||
|
||||
bool isPathGridOccupied = MWBase::Environment::get().getMechanicsManager()->isAnyActorInRange(
|
||||
PathFinder::makeOsgVec3(worldDest), 60);
|
||||
@ -756,13 +746,12 @@ namespace MWMechanics
|
||||
if (points.empty())
|
||||
return;
|
||||
|
||||
int initialSize = points.size();
|
||||
bool isOccupied = false;
|
||||
// AI will try to move the NPC towards every neighboring node until suitable place will be found
|
||||
for (int i = 0; i < initialSize; i++)
|
||||
while (!points.empty())
|
||||
{
|
||||
int randomIndex = Misc::Rng::rollDice(points.size(), prng);
|
||||
ESM::Pathgrid::Point connDest = points[randomIndex];
|
||||
const ESM::Pathgrid::Point& connDest = points[randomIndex];
|
||||
|
||||
// add an offset towards random neighboring node
|
||||
osg::Vec3f dir = PathFinder::makeOsgVec3(connDest) - PathFinder::makeOsgVec3(dest);
|
||||
@ -774,8 +763,7 @@ namespace MWMechanics
|
||||
// move for 5-15% towards random neighboring node
|
||||
dest
|
||||
= PathFinder::makePathgridPoint(PathFinder::makeOsgVec3(dest) + dir * (j * 5 * length / 100.f));
|
||||
worldDest = dest;
|
||||
ToWorldCoordinates(worldDest, actor.getCell()->getCell());
|
||||
worldDest = converter.toWorldPoint(dest);
|
||||
|
||||
isOccupied = MWBase::Environment::get().getMechanicsManager()->isAnyActorInRange(
|
||||
PathFinder::makeOsgVec3(worldDest), 60);
|
||||
@ -800,7 +788,7 @@ namespace MWMechanics
|
||||
// underground. Adding 20 in adjustPosition() is not enough.
|
||||
dest.mZ += 60;
|
||||
|
||||
ToWorldCoordinates(dest, actor.getCell()->getCell());
|
||||
converter.toWorld(dest);
|
||||
|
||||
state.moveIn(std::make_unique<AiWanderStorage>());
|
||||
|
||||
@ -847,15 +835,15 @@ namespace MWMechanics
|
||||
if (mDistance && storage.mCanWanderAlongPathGrid && !actor.getClass().isPureWaterCreature(actor))
|
||||
{
|
||||
// get NPC's position in local (i.e. cell) coordinates
|
||||
osg::Vec3f npcPos(mInitialActorPosition);
|
||||
Misc::CoordinateConverter(cell).toLocal(npcPos);
|
||||
auto converter = Misc::CoordinateConverter(cell);
|
||||
const osg::Vec3f npcPos = converter.toLocalVec3(mInitialActorPosition);
|
||||
|
||||
// Find closest pathgrid point
|
||||
int closestPointIndex = PathFinder::getClosestPoint(pathgrid, npcPos);
|
||||
|
||||
// mAllowedNodes for this actor with pathgrid point indexes based on mDistance
|
||||
// and if the point is connected to the closest current point
|
||||
// NOTE: mPoints and mAllowedNodes are in local coordinates
|
||||
// NOTE: mPoints is in local coordinates
|
||||
int pointIndex = 0;
|
||||
for (unsigned int counter = 0; counter < pathgrid->mPoints.size(); counter++)
|
||||
{
|
||||
@ -863,17 +851,18 @@ namespace MWMechanics
|
||||
if ((npcPos - nodePos).length2() <= mDistance * mDistance
|
||||
&& getPathGridGraph(cellStore).isPointConnected(closestPointIndex, counter))
|
||||
{
|
||||
storage.mAllowedNodes.push_back(pathgrid->mPoints[counter]);
|
||||
storage.mAllowedNodes.push_back(converter.toWorldPoint(pathgrid->mPoints[counter]));
|
||||
pointIndex = counter;
|
||||
}
|
||||
}
|
||||
if (storage.mAllowedNodes.size() == 1)
|
||||
{
|
||||
AddNonPathGridAllowedPoints(npcPos, pathgrid, pointIndex, storage);
|
||||
storage.mAllowedNodes.push_back(PathFinder::makePathgridPoint(mInitialActorPosition));
|
||||
addNonPathGridAllowedPoints(pathgrid, pointIndex, storage, converter);
|
||||
}
|
||||
if (!storage.mAllowedNodes.empty())
|
||||
{
|
||||
SetCurrentNodeToClosestAllowedNode(npcPos, storage);
|
||||
setCurrentNodeToClosestAllowedNode(storage);
|
||||
}
|
||||
}
|
||||
|
||||
@ -884,15 +873,15 @@ namespace MWMechanics
|
||||
// additional points for NPC to wander to are:
|
||||
// 1. NPC's initial location
|
||||
// 2. Partway along the path between the point and its connected points.
|
||||
void AiWander::AddNonPathGridAllowedPoints(
|
||||
osg::Vec3f npcPos, const ESM::Pathgrid* pathGrid, int pointIndex, AiWanderStorage& storage)
|
||||
void AiWander::addNonPathGridAllowedPoints(const ESM::Pathgrid* pathGrid, int pointIndex, AiWanderStorage& storage,
|
||||
const Misc::CoordinateConverter& converter)
|
||||
{
|
||||
storage.mAllowedNodes.push_back(PathFinder::makePathgridPoint(npcPos));
|
||||
for (auto& edge : pathGrid->mEdges)
|
||||
{
|
||||
if (edge.mV0 == pointIndex)
|
||||
{
|
||||
AddPointBetweenPathGridPoints(pathGrid->mPoints[edge.mV0], pathGrid->mPoints[edge.mV1], storage);
|
||||
AddPointBetweenPathGridPoints(converter.toWorldPoint(pathGrid->mPoints[edge.mV0]),
|
||||
converter.toWorldPoint(pathGrid->mPoints[edge.mV1]), storage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -913,17 +902,17 @@ namespace MWMechanics
|
||||
storage.mAllowedNodes.push_back(PathFinder::makePathgridPoint(vectorStart + delta));
|
||||
}
|
||||
|
||||
void AiWander::SetCurrentNodeToClosestAllowedNode(const osg::Vec3f& npcPos, AiWanderStorage& storage)
|
||||
void AiWander::setCurrentNodeToClosestAllowedNode(AiWanderStorage& storage)
|
||||
{
|
||||
float distanceToClosestNode = std::numeric_limits<float>::max();
|
||||
unsigned int index = 0;
|
||||
for (unsigned int counterThree = 0; counterThree < storage.mAllowedNodes.size(); counterThree++)
|
||||
size_t index = 0;
|
||||
for (size_t i = 0; i < storage.mAllowedNodes.size(); ++i)
|
||||
{
|
||||
osg::Vec3f nodePos(PathFinder::makeOsgVec3(storage.mAllowedNodes[counterThree]));
|
||||
float tempDist = (npcPos - nodePos).length2();
|
||||
osg::Vec3f nodePos(PathFinder::makeOsgVec3(storage.mAllowedNodes[i]));
|
||||
float tempDist = (mInitialActorPosition - nodePos).length2();
|
||||
if (tempDist < distanceToClosestNode)
|
||||
{
|
||||
index = counterThree;
|
||||
index = i;
|
||||
distanceToClosestNode = tempDist;
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,11 @@ namespace ESM
|
||||
}
|
||||
}
|
||||
|
||||
namespace Misc
|
||||
{
|
||||
class CoordinateConverter;
|
||||
}
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
/// \brief This class holds the variables AiWander needs which are deleted if the package becomes inactive.
|
||||
@ -45,7 +50,6 @@ namespace MWMechanics
|
||||
bool mPopulateAvailableNodes;
|
||||
|
||||
// allowed pathgrid nodes based on mDistance from the spawn point
|
||||
// in local coordinates of mCell
|
||||
std::vector<ESM::Pathgrid::Point> mAllowedNodes;
|
||||
|
||||
ESM::Pathgrid::Point mCurrentNode;
|
||||
@ -154,13 +158,10 @@ namespace MWMechanics
|
||||
GroupIndex_MaxIdle = 9
|
||||
};
|
||||
|
||||
/// convert point from local (i.e. cell) to world coordinates
|
||||
void ToWorldCoordinates(ESM::Pathgrid::Point& point, const ESM::Cell* cell);
|
||||
void setCurrentNodeToClosestAllowedNode(AiWanderStorage& storage);
|
||||
|
||||
void SetCurrentNodeToClosestAllowedNode(const osg::Vec3f& npcPos, AiWanderStorage& storage);
|
||||
|
||||
void AddNonPathGridAllowedPoints(
|
||||
osg::Vec3f npcPos, const ESM::Pathgrid* pathGrid, int pointIndex, AiWanderStorage& storage);
|
||||
void addNonPathGridAllowedPoints(const ESM::Pathgrid* pathGrid, int pointIndex, AiWanderStorage& storage,
|
||||
const Misc::CoordinateConverter& converter);
|
||||
|
||||
void AddPointBetweenPathGridPoints(
|
||||
const ESM::Pathgrid::Point& start, const ESM::Pathgrid::Point& end, AiWanderStorage& storage);
|
||||
|
@ -29,12 +29,25 @@ namespace Misc
|
||||
point.mY += mCellY;
|
||||
}
|
||||
|
||||
/// in-place conversion from world to local
|
||||
void toLocal(ESM::Pathgrid::Point& point) const
|
||||
{
|
||||
point.mX -= mCellX;
|
||||
point.mY -= mCellY;
|
||||
}
|
||||
|
||||
ESM::Pathgrid::Point toWorldPoint(ESM::Pathgrid::Point point) const
|
||||
{
|
||||
toWorld(point);
|
||||
return point;
|
||||
}
|
||||
|
||||
ESM::Pathgrid::Point toLocalPoint(ESM::Pathgrid::Point point) const
|
||||
{
|
||||
toLocal(point);
|
||||
return point;
|
||||
}
|
||||
|
||||
/// in-place conversion from local to world
|
||||
void toWorld(osg::Vec3f& point) const
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user