1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-21 09:39:56 +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:
elsid 2023-05-10 22:26:51 +02:00
parent f7ebd9b9b4
commit aa9fb33a18
No known key found for this signature in database
GPG Key ID: 4DE04C198CBA7625
2 changed files with 44 additions and 8 deletions

View File

@ -189,17 +189,18 @@ namespace MWRender
int cellY = cell->getCell()->getGridY();
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;
requestExteriorMap(cell, segment);
segment.needUpdate = false;
segment.mLastRenderNeighbourFlags = neighbourFlags;
}
void LocalMap::addCell(MWWorld::CellStore* cell)
{
if (cell->isExterior())
mExteriorSegments[std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY())].needUpdate
= true;
mExteriorSegments.emplace(
std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY()), MapSegment{});
}
void LocalMap::removeExteriorCell(int x, int y)
@ -211,7 +212,9 @@ namespace MWRender
{
saveFogOfWar(cell);
if (!cell->isExterior())
if (cell->isExterior())
mExteriorSegments.erase({ cell->getCell()->getGridX(), cell->getCell()->getGridY() });
else
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()
{
if (mFogOfWarTexture)

View File

@ -1,6 +1,7 @@
#ifndef GAME_RENDER_LOCALMAP_H
#define GAME_RENDER_LOCALMAP_H
#include <cstdint>
#include <map>
#include <set>
#include <vector>
@ -107,6 +108,18 @@ namespace MWRender
typedef std::set<std::pair<int, int>> Grid;
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
{
void initFogOfWar();
@ -114,12 +127,11 @@ namespace MWRender
void saveFogOfWar(ESM::FogTexture& fog) const;
void createFogOfWarTexture();
std::uint8_t mLastRenderNeighbourFlags = 0;
bool mHasFogState = false;
osg::ref_ptr<osg::Texture2D> mMapTexture;
osg::ref_ptr<osg::Texture2D> mFogOfWarTexture;
osg::ref_ptr<osg::Image> mFogOfWarImage;
bool needUpdate = true;
bool mHasFogState = false;
};
typedef std::map<std::pair<int, int>, MapSegment> SegmentMap;
@ -147,6 +159,8 @@ namespace MWRender
bool mInterior;
osg::BoundingBox mBounds;
std::uint8_t getExteriorNeighbourFlags(int cellX, int cellY) const;
};
}