mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-04 03:40:14 +00:00
Work around pathgrid record limitation (Fixes #2195)
This commit is contained in:
parent
6c8a662042
commit
0fe7500f74
@ -382,7 +382,7 @@ namespace MWMechanics
|
|||||||
{
|
{
|
||||||
// infrequently used, therefore no benefit in caching it as a member
|
// infrequently used, therefore no benefit in caching it as a member
|
||||||
const ESM::Pathgrid *
|
const ESM::Pathgrid *
|
||||||
pathgrid = world->getStore().get<ESM::Pathgrid>().search(*cell);
|
pathgrid = world->getStore().get<ESM::Pathgrid>().search(*cell, world->getCellName(currentCell));
|
||||||
|
|
||||||
// cache the current cell location
|
// cache the current cell location
|
||||||
cachedCellX = cell->mData.mX;
|
cachedCellX = cell->mData.mX;
|
||||||
|
@ -188,7 +188,8 @@ namespace MWMechanics
|
|||||||
if(mCell != cell || !mPathgrid)
|
if(mCell != cell || !mPathgrid)
|
||||||
{
|
{
|
||||||
mCell = cell;
|
mCell = cell;
|
||||||
mPathgrid = MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*mCell->getCell());
|
mPathgrid = MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*mCell->getCell(),
|
||||||
|
MWBase::Environment::get().getWorld()->getCellName(mCell));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refer to AiWander reseach topic on openmw forums for some background.
|
// Refer to AiWander reseach topic on openmw forums for some background.
|
||||||
|
@ -95,7 +95,7 @@ namespace MWMechanics
|
|||||||
* +---------------->
|
* +---------------->
|
||||||
* high cost
|
* high cost
|
||||||
*/
|
*/
|
||||||
bool PathgridGraph::load(const ESM::Cell* cell)
|
bool PathgridGraph::load(const MWWorld::CellStore *cell)
|
||||||
{
|
{
|
||||||
if(!cell)
|
if(!cell)
|
||||||
return false;
|
return false;
|
||||||
@ -103,9 +103,10 @@ namespace MWMechanics
|
|||||||
if(mIsGraphConstructed)
|
if(mIsGraphConstructed)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
mCell = cell;
|
mCell = cell->getCell();
|
||||||
mIsExterior = cell->isExterior();
|
mIsExterior = cell->getCell()->isExterior();
|
||||||
mPathgrid = MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*cell);
|
mPathgrid = MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*cell->getCell(),
|
||||||
|
MWBase::Environment::get().getWorld()->getCellName(cell));
|
||||||
|
|
||||||
if(!mPathgrid)
|
if(!mPathgrid)
|
||||||
return false;
|
return false;
|
||||||
|
@ -21,7 +21,7 @@ namespace MWMechanics
|
|||||||
public:
|
public:
|
||||||
PathgridGraph();
|
PathgridGraph();
|
||||||
|
|
||||||
bool load(const ESM::Cell *cell);
|
bool load(const MWWorld::CellStore *cell);
|
||||||
|
|
||||||
// returns true if end point is strongly connected (i.e. reachable
|
// returns true if end point is strongly connected (i.e. reachable
|
||||||
// from start point) both start and end are pathgrid point indexes
|
// from start point) both start and end are pathgrid point indexes
|
||||||
|
@ -231,8 +231,9 @@ void Debugging::togglePathgrid()
|
|||||||
|
|
||||||
void Debugging::enableCellPathgrid(MWWorld::CellStore *store)
|
void Debugging::enableCellPathgrid(MWWorld::CellStore *store)
|
||||||
{
|
{
|
||||||
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||||
const ESM::Pathgrid *pathgrid =
|
const ESM::Pathgrid *pathgrid =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*store->getCell());
|
world->getStore().get<ESM::Pathgrid>().search(*store->getCell(), world->getCellName(store));
|
||||||
if (!pathgrid) return;
|
if (!pathgrid) return;
|
||||||
|
|
||||||
Vector3 cellPathGridPos(0, 0, 0);
|
Vector3 cellPathGridPos(0, 0, 0);
|
||||||
|
@ -413,7 +413,7 @@ namespace MWWorld
|
|||||||
|
|
||||||
// TODO: the pathgrid graph only needs to be loaded for active cells, so move this somewhere else.
|
// TODO: the pathgrid graph only needs to be loaded for active cells, so move this somewhere else.
|
||||||
// In a simple test, loading the graph for all cells in MW + expansions took 200 ms
|
// In a simple test, loading the graph for all cells in MW + expansions took 200 ms
|
||||||
mPathgridGraph.load(mCell);
|
mPathgridGraph.load(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -843,88 +843,59 @@ namespace MWWorld
|
|||||||
class Store<ESM::Pathgrid> : public StoreBase
|
class Store<ESM::Pathgrid> : public StoreBase
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
typedef std::map<std::string, ESM::Pathgrid> Interior;
|
// Unfortunately the Pathgrid record model does not specify whether the pathgrid belongs to an interior or exterior cell.
|
||||||
typedef std::map<std::pair<int, int>, ESM::Pathgrid> Exterior;
|
// For interior cells, mCell is the cell name, but for exterior cells it is either the cell name or if that doesn't exist, the cell's region name.
|
||||||
|
// mX and mY will be (0,0) for interior cells, but there is also an exterior cell with the coordinates of (0,0), so that doesn't help.
|
||||||
|
// This is why we keep both interior and exterior pathgrids in the same container here.
|
||||||
|
typedef std::pair<std::string, std::pair<int, int> > PathgridKey;
|
||||||
|
typedef std::map<PathgridKey, ESM::Pathgrid> Static;
|
||||||
|
|
||||||
Interior mInt;
|
Static mStatic;
|
||||||
Exterior mExt;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void load(ESM::ESMReader &esm, const std::string &id) {
|
void load(ESM::ESMReader &esm, const std::string &id) {
|
||||||
|
|
||||||
ESM::Pathgrid pathgrid;
|
ESM::Pathgrid pathgrid;
|
||||||
pathgrid.load(esm);
|
pathgrid.load(esm);
|
||||||
|
|
||||||
|
PathgridKey key = std::make_pair(pathgrid.mCell, std::make_pair(pathgrid.mData.mX, pathgrid.mData.mY));
|
||||||
|
|
||||||
// Try to overwrite existing record
|
// Try to overwrite existing record
|
||||||
if (!pathgrid.mCell.empty())
|
std::pair<Static::iterator, bool> ret = mStatic.insert(std::make_pair(key, pathgrid));
|
||||||
{
|
if (!ret.second)
|
||||||
std::pair<Interior::iterator, bool> ret = mInt.insert(std::make_pair(pathgrid.mCell, pathgrid));
|
ret.first->second = pathgrid;
|
||||||
if (!ret.second)
|
|
||||||
ret.first->second = pathgrid;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::pair<Exterior::iterator, bool> ret = mExt.insert(std::make_pair(std::make_pair(pathgrid.mData.mX, pathgrid.mData.mY),
|
|
||||||
pathgrid));
|
|
||||||
if (!ret.second)
|
|
||||||
ret.first->second = pathgrid;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t getSize() const {
|
size_t getSize() const {
|
||||||
return mInt.size() + mExt.size();
|
return mStatic.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setUp() {
|
void setUp() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const ESM::Pathgrid *search(int x, int y) const {
|
const ESM::Pathgrid *search(const ESM::Cell &cell, const std::string& cellName) const {
|
||||||
Exterior::const_iterator it = mExt.find(std::make_pair(x,y));
|
int x=0,y=0;
|
||||||
if (it != mExt.end())
|
if (!(cell.mData.mFlags & ESM::Cell::Interior))
|
||||||
|
{
|
||||||
|
x = cell.mData.mX;
|
||||||
|
y = cell.mData.mY;
|
||||||
|
}
|
||||||
|
PathgridKey key = std::make_pair(cellName, std::make_pair(x,y));
|
||||||
|
|
||||||
|
Static::const_iterator it = mStatic.find(key);
|
||||||
|
if (it != mStatic.end())
|
||||||
return &(it->second);
|
return &(it->second);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ESM::Pathgrid *find(int x, int y) const {
|
const ESM::Pathgrid *find(const ESM::Cell &cell, const std::string& cellName) const {
|
||||||
const ESM::Pathgrid *ptr = search(x, y);
|
const ESM::Pathgrid* pathgrid = search(cell, cellName);
|
||||||
if (ptr == 0) {
|
if (pathgrid == 0) {
|
||||||
std::ostringstream msg;
|
std::ostringstream msg;
|
||||||
msg << "Pathgrid at (" << x << ", " << y << ") not found";
|
msg << "Pathgrid in cell '" << cellName << "' not found";
|
||||||
throw std::runtime_error(msg.str());
|
throw std::runtime_error(msg.str());
|
||||||
}
|
}
|
||||||
return ptr;
|
return pathgrid;
|
||||||
}
|
|
||||||
|
|
||||||
const ESM::Pathgrid *search(const std::string &name) const {
|
|
||||||
Interior::const_iterator it = mInt.find(name);
|
|
||||||
if (it != mInt.end())
|
|
||||||
return &(it->second);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ESM::Pathgrid *find(const std::string &name) const {
|
|
||||||
const ESM::Pathgrid *ptr = search(name);
|
|
||||||
if (ptr == 0) {
|
|
||||||
std::ostringstream msg;
|
|
||||||
msg << "Pathgrid in cell '" << name << "' not found";
|
|
||||||
throw std::runtime_error(msg.str());
|
|
||||||
}
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ESM::Pathgrid *search(const ESM::Cell &cell) const {
|
|
||||||
if (cell.mData.mFlags & ESM::Cell::Interior) {
|
|
||||||
return search(cell.mName);
|
|
||||||
}
|
|
||||||
return search(cell.mData.mX, cell.mData.mY);
|
|
||||||
}
|
|
||||||
|
|
||||||
const ESM::Pathgrid *find(const ESM::Cell &cell) const {
|
|
||||||
if (cell.mData.mFlags & ESM::Cell::Interior) {
|
|
||||||
return find(cell.mName);
|
|
||||||
}
|
|
||||||
return find(cell.mData.mX, cell.mData.mY);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user