mirror of
https://github.com/OpenMW/openmw.git
synced 2025-04-27 20:36:50 +00:00
Update cell local map on different neighbour cells
Save which neighbour cells were active when local map for a cell is rendered. Update when intersection of currently loaded cells is different from stored. If map was rendered when all neighbours were loaded no more updates will happen.
This commit is contained in:
parent
f7ebd9b9b4
commit
aa9fb33a18
2 changed files with 44 additions and 8 deletions
|
@ -189,17 +189,18 @@ namespace MWRender
|
||||||
int cellY = cell->getCell()->getGridY();
|
int cellY = cell->getCell()->getGridY();
|
||||||
|
|
||||||
MapSegment& segment = mExteriorSegments[std::make_pair(cellX, cellY)];
|
MapSegment& segment = mExteriorSegments[std::make_pair(cellX, cellY)];
|
||||||
if (!segment.needUpdate)
|
const std::uint8_t neighbourFlags = getExteriorNeighbourFlags(cellX, cellY);
|
||||||
|
if ((segment.mLastRenderNeighbourFlags & neighbourFlags) == neighbourFlags)
|
||||||
return;
|
return;
|
||||||
requestExteriorMap(cell, segment);
|
requestExteriorMap(cell, segment);
|
||||||
segment.needUpdate = false;
|
segment.mLastRenderNeighbourFlags = neighbourFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalMap::addCell(MWWorld::CellStore* cell)
|
void LocalMap::addCell(MWWorld::CellStore* cell)
|
||||||
{
|
{
|
||||||
if (cell->isExterior())
|
if (cell->isExterior())
|
||||||
mExteriorSegments[std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY())].needUpdate
|
mExteriorSegments.emplace(
|
||||||
= true;
|
std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY()), MapSegment{});
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalMap::removeExteriorCell(int x, int y)
|
void LocalMap::removeExteriorCell(int x, int y)
|
||||||
|
@ -211,7 +212,9 @@ namespace MWRender
|
||||||
{
|
{
|
||||||
saveFogOfWar(cell);
|
saveFogOfWar(cell);
|
||||||
|
|
||||||
if (!cell->isExterior())
|
if (cell->isExterior())
|
||||||
|
mExteriorSegments.erase({ cell->getCell()->getGridX(), cell->getCell()->getGridY() });
|
||||||
|
else
|
||||||
mInteriorSegments.clear();
|
mInteriorSegments.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,6 +571,25 @@ namespace MWRender
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::uint8_t LocalMap::getExteriorNeighbourFlags(int cellX, int cellY) const
|
||||||
|
{
|
||||||
|
constexpr std::tuple<NeighbourCellFlag, int, int> flags[] = {
|
||||||
|
{ NeighbourCellTopLeft, -1, -1 },
|
||||||
|
{ NeighbourCellTopCenter, 0, -1 },
|
||||||
|
{ NeighbourCellTopRight, 1, -1 },
|
||||||
|
{ NeighbourCellMiddleLeft, -1, 0 },
|
||||||
|
{ NeighbourCellMiddleRight, 1, 0 },
|
||||||
|
{ NeighbourCellBottomLeft, -1, 1 },
|
||||||
|
{ NeighbourCellBottomCenter, 0, 1 },
|
||||||
|
{ NeighbourCellBottomRight, 1, 1 },
|
||||||
|
};
|
||||||
|
std::uint8_t result = 0;
|
||||||
|
for (const auto& [flag, dx, dy] : flags)
|
||||||
|
if (mExteriorSegments.contains(std::pair(cellX + dx, cellY + dy)))
|
||||||
|
result |= flag;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void LocalMap::MapSegment::createFogOfWarTexture()
|
void LocalMap::MapSegment::createFogOfWarTexture()
|
||||||
{
|
{
|
||||||
if (mFogOfWarTexture)
|
if (mFogOfWarTexture)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef GAME_RENDER_LOCALMAP_H
|
#ifndef GAME_RENDER_LOCALMAP_H
|
||||||
#define GAME_RENDER_LOCALMAP_H
|
#define GAME_RENDER_LOCALMAP_H
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -107,6 +108,18 @@ namespace MWRender
|
||||||
typedef std::set<std::pair<int, int>> Grid;
|
typedef std::set<std::pair<int, int>> Grid;
|
||||||
Grid mCurrentGrid;
|
Grid mCurrentGrid;
|
||||||
|
|
||||||
|
enum NeighbourCellFlag : std::uint8_t
|
||||||
|
{
|
||||||
|
NeighbourCellTopLeft = 1,
|
||||||
|
NeighbourCellTopCenter = 1 << 1,
|
||||||
|
NeighbourCellTopRight = 1 << 2,
|
||||||
|
NeighbourCellMiddleLeft = 1 << 3,
|
||||||
|
NeighbourCellMiddleRight = 1 << 4,
|
||||||
|
NeighbourCellBottomLeft = 1 << 5,
|
||||||
|
NeighbourCellBottomCenter = 1 << 6,
|
||||||
|
NeighbourCellBottomRight = 1 << 7,
|
||||||
|
};
|
||||||
|
|
||||||
struct MapSegment
|
struct MapSegment
|
||||||
{
|
{
|
||||||
void initFogOfWar();
|
void initFogOfWar();
|
||||||
|
@ -114,12 +127,11 @@ namespace MWRender
|
||||||
void saveFogOfWar(ESM::FogTexture& fog) const;
|
void saveFogOfWar(ESM::FogTexture& fog) const;
|
||||||
void createFogOfWarTexture();
|
void createFogOfWarTexture();
|
||||||
|
|
||||||
|
std::uint8_t mLastRenderNeighbourFlags = 0;
|
||||||
|
bool mHasFogState = false;
|
||||||
osg::ref_ptr<osg::Texture2D> mMapTexture;
|
osg::ref_ptr<osg::Texture2D> mMapTexture;
|
||||||
osg::ref_ptr<osg::Texture2D> mFogOfWarTexture;
|
osg::ref_ptr<osg::Texture2D> mFogOfWarTexture;
|
||||||
osg::ref_ptr<osg::Image> mFogOfWarImage;
|
osg::ref_ptr<osg::Image> mFogOfWarImage;
|
||||||
|
|
||||||
bool needUpdate = true;
|
|
||||||
bool mHasFogState = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<std::pair<int, int>, MapSegment> SegmentMap;
|
typedef std::map<std::pair<int, int>, MapSegment> SegmentMap;
|
||||||
|
@ -147,6 +159,8 @@ namespace MWRender
|
||||||
|
|
||||||
bool mInterior;
|
bool mInterior;
|
||||||
osg::BoundingBox mBounds;
|
osg::BoundingBox mBounds;
|
||||||
|
|
||||||
|
std::uint8_t getExteriorNeighbourFlags(int cellX, int cellY) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue