Merge branch 'fix_esm4_ai' into 'master'

Fix AI in ESM4 cells

See merge request OpenMW/openmw!3338
macos_ci_fix
jvoisin 1 year ago
commit 4cf80cdac2

@ -371,7 +371,8 @@ namespace MWMechanics
&& !actor.getClass().isPureWaterCreature(actor))
{
ESM::Pathgrid::PointList points;
Misc::CoordinateConverter coords(*storage.mCell->getCell());
const Misc::CoordinateConverter coords
= Misc::makeCoordinateConverter(*storage.mCell->getCell());
osg::Vec3f localPos = actor.getRefData().getPosition().asVec3();
coords.toLocal(localPos);

@ -421,7 +421,7 @@ bool MWMechanics::AiPackage::isNearInactiveCell(osg::Vec3f position)
if (playerCell->isExterior())
{
// get actor's distance from origin of center cell
Misc::CoordinateConverter(*playerCell).toLocal(position);
Misc::makeCoordinateConverter(*playerCell).toLocal(position);
// currently assumes 3 x 3 grid for exterior cells, with player at center cell.
// AI shuts down actors before they reach edges of 3 x 3 grid.

@ -730,7 +730,7 @@ namespace MWMechanics
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
int index = Misc::Rng::rollDice(storage.mAllowedNodes.size(), prng);
ESM::Pathgrid::Point worldDest = storage.mAllowedNodes[index];
auto converter = Misc::CoordinateConverter(*actor.getCell()->getCell());
const Misc::CoordinateConverter converter = Misc::makeCoordinateConverter(*actor.getCell()->getCell());
ESM::Pathgrid::Point dest = converter.toLocalPoint(worldDest);
bool isPathGridOccupied = MWBase::Environment::get().getMechanicsManager()->isAnyActorInRange(
@ -835,7 +835,7 @@ namespace MWMechanics
if (mDistance && storage.mCanWanderAlongPathGrid && !actor.getClass().isPureWaterCreature(actor))
{
// get NPC's position in local (i.e. cell) coordinates
auto converter = Misc::CoordinateConverter(*cellStore->getCell());
const Misc::CoordinateConverter converter = Misc::makeCoordinateConverter(*cellStore->getCell());
const osg::Vec3f npcPos = converter.toLocalVec3(mInitialActorPosition);
// Find closest pathgrid point

@ -189,7 +189,7 @@ namespace MWMechanics
return;
// NOTE: getClosestPoint expects local coordinates
Misc::CoordinateConverter converter(*mCell->getCell());
const Misc::CoordinateConverter converter = Misc::makeCoordinateConverter(*mCell->getCell());
// NOTE: It is possible that getClosestPoint returns a pathgrind point index
// that is unreachable in some situations. e.g. actor is standing

@ -481,11 +481,9 @@ namespace MWPhysics
mHeightFields.erase(heightfield);
}
const HeightField* PhysicsSystem::getHeightField(ESM::ExteriorCellLocation cellIndex) const
const HeightField* PhysicsSystem::getHeightField(int x, int y) const
{
if (ESM::isEsm4Ext(cellIndex.mWorldspace))
return nullptr;
const auto heightField = mHeightFields.find(std::make_pair(cellIndex.mX, cellIndex.mY));
const auto heightField = mHeightFields.find(std::make_pair(x, y));
if (heightField == mHeightFields.end())
return nullptr;
return heightField->second.get();

@ -189,7 +189,7 @@ namespace MWPhysics
void removeHeightField(int x, int y);
const HeightField* getHeightField(ESM::ExteriorCellLocation cellIndex) const;
const HeightField* getHeightField(int x, int y) const;
bool toggleCollisionMode();

@ -116,7 +116,7 @@ namespace MWRender
return;
osg::Vec3f cellPathGridPos(0, 0, 0);
Misc::CoordinateConverter(*store->getCell()).toWorld(cellPathGridPos);
Misc::makeCoordinateConverter(*store->getCell()).toWorld(cellPathGridPos);
osg::ref_ptr<osg::PositionAttitudeTransform> cellPathGrid = new osg::PositionAttitudeTransform;
cellPathGrid->setPosition(cellPathGridPos);

@ -346,10 +346,7 @@ namespace MWWorld
if (cell->getCell()->isExterior())
{
if (mPhysics->getHeightField(ESM::ExteriorCellLocation(cellX, cellY, cell->getCell()->getWorldSpace()))
!= nullptr)
mNavigator.removeHeightfield(osg::Vec2i(cellX, cellY), navigatorUpdateGuard);
mNavigator.removeHeightfield(osg::Vec2i(cellX, cellY), navigatorUpdateGuard);
mPhysics->removeHeightField(cellX, cellY);
}
@ -414,7 +411,7 @@ namespace MWWorld
mPhysics->addHeightField(defaultHeight.data(), cellX, cellY, worldsize, verts,
ESM::Land::DEFAULT_HEIGHT, ESM::Land::DEFAULT_HEIGHT, land.get());
}
if (const auto heightField = mPhysics->getHeightField(cellIndex))
if (const auto heightField = mPhysics->getHeightField(cellX, cellY))
{
const osg::Vec2i cellPosition(cellX, cellY);
const btVector3& origin = heightField->getCollisionObject()->getWorldTransform().getOrigin();
@ -469,7 +466,7 @@ namespace MWWorld
if (cellVariant.isExterior())
{
if (const auto heightField = mPhysics->getHeightField(cellIndex))
if (const auto heightField = mPhysics->getHeightField(cellX, cellY))
mNavigator.addWater(
osg::Vec2i(cellX, cellY), ESM::Land::REAL_SIZE, waterLevel, navigatorUpdateGuard);
}

@ -133,7 +133,7 @@ namespace DetourNavigator
void NavigatorImpl::addPathgrid(const ESM::Cell& cell, const ESM::Pathgrid& pathgrid)
{
Misc::CoordinateConverter converter(&cell);
const Misc::CoordinateConverter converter = Misc::makeCoordinateConverter(cell);
for (const auto& edge : pathgrid.mEdges)
{
const auto src = Misc::Convert::makeOsgVec3f(converter.toWorldPoint(pathgrid.mPoints[edge.mV0]));

@ -5,11 +5,14 @@
#include <string>
#include <vector>
#include "cellref.hpp"
#include "components/esm/defs.hpp"
#include "components/esm/esmcommon.hpp"
#include "components/esm/refid.hpp"
#include <components/misc/constants.hpp>
#include "cellref.hpp"
namespace MWWorld
{
class ESMStore;
@ -70,6 +73,8 @@ namespace ESM
constexpr static RecNameInts sRecordId = REC_CELL;
static constexpr int sSize = Constants::CellSizeInUnits;
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string_view getRecordType() { return "Cell"; }

@ -35,6 +35,7 @@
#include <components/esm/refid.hpp>
#include <components/esm/util.hpp>
#include <components/esm4/reader.hpp>
#include <components/misc/constants.hpp>
#include "lighting.hpp"
@ -62,6 +63,8 @@ namespace ESM4
// The cells need to be organised under world spaces.
struct Cell
{
static constexpr int sSize = Constants::ESM4CellSizeInUnits;
ESM::RefId mId; // from the header
std::uint32_t mFlags = 0; // from the header, see enum type RecordFlag for details

@ -3,9 +3,9 @@
#include <components/esm/esmbridge.hpp>
#include <components/esm3/loadcell.hpp>
#include <components/esm3/loadland.hpp>
#include <components/esm3/loadpgrd.hpp>
#include <components/esm4/loadcell.hpp>
#include <components/misc/constants.hpp>
namespace Misc
{
@ -13,21 +13,9 @@ namespace Misc
class CoordinateConverter
{
public:
CoordinateConverter(bool exterior, int cellX, int cellY)
: mCellX(exterior ? cellX * ESM::Land::REAL_SIZE : 0)
, mCellY(exterior ? cellY * ESM::Land::REAL_SIZE : 0)
{
}
explicit CoordinateConverter(const ESM::CellVariant& cell)
: CoordinateConverter(cell.isEsm4() ? cell.getEsm4().isExterior() : cell.getEsm3().isExterior(),
cell.isEsm4() ? cell.getEsm4().getGridX() : cell.getEsm3().getGridX(),
cell.isEsm4() ? cell.getEsm4().getGridY() : cell.getEsm3().getGridY())
{
}
explicit CoordinateConverter(const ESM::Cell* cell)
: CoordinateConverter(cell->isExterior(), cell->getGridX(), cell->getGridY())
explicit CoordinateConverter(int cellX, int cellY)
: mCellX(cellX)
, mCellY(cellY)
{
}
@ -81,6 +69,29 @@ namespace Misc
int mCellX;
int mCellY;
};
template <class T>
CoordinateConverter makeCoordinateConverterImpl(const T& cell)
{
if (cell.isExterior())
return CoordinateConverter(cell.sSize * cell.getGridX(), cell.sSize * cell.getGridY());
return CoordinateConverter(0, 0);
}
inline CoordinateConverter makeCoordinateConverter(const ESM::Cell& cell)
{
return makeCoordinateConverterImpl(cell);
}
inline CoordinateConverter makeCoordinateConverter(const ESM4::Cell& cell)
{
return makeCoordinateConverterImpl(cell);
}
inline CoordinateConverter makeCoordinateConverter(const ESM::CellVariant& cell)
{
return visit([](const auto& v) { return makeCoordinateConverterImpl(v); }, cell);
}
}
#endif

Loading…
Cancel
Save