1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-06-26 19:41:34 +00:00

land manager cache's key is an ExteriorCellLocation

ESM4::Land is now a ESM::LandData
This commit is contained in:
florent.teppe 2023-05-15 00:34:17 +02:00
parent e0fa15b727
commit fffcf52316
8 changed files with 69 additions and 16 deletions

View file

@ -12,7 +12,7 @@ namespace MWRender
{ {
LandManager::LandManager(int loadFlags) LandManager::LandManager(int loadFlags)
: GenericResourceManager<std::pair<int, int>>(nullptr) : GenericResourceManager<ESM::ExteriorCellLocation>(nullptr)
, mLoadFlags(loadFlags) , mLoadFlags(loadFlags)
{ {
mCache = new CacheType; mCache = new CacheType;
@ -22,9 +22,7 @@ namespace MWRender
{ {
if (ESM::isEsm4Ext(cellIndex.mWorldspace)) if (ESM::isEsm4Ext(cellIndex.mWorldspace))
return osg::ref_ptr<ESMTerrain::LandObject>(nullptr); return osg::ref_ptr<ESMTerrain::LandObject>(nullptr);
int x = cellIndex.mX; osg::ref_ptr<osg::Object> obj = mCache->getRefFromObjectCache(cellIndex);
int y = cellIndex.mY;
osg::ref_ptr<osg::Object> obj = mCache->getRefFromObjectCache(std::make_pair(x, y));
if (obj) if (obj)
return static_cast<ESMTerrain::LandObject*>(obj.get()); return static_cast<ESMTerrain::LandObject*>(obj.get());
else else
@ -32,11 +30,11 @@ namespace MWRender
const auto world = MWBase::Environment::get().getWorld(); const auto world = MWBase::Environment::get().getWorld();
if (!world) if (!world)
return nullptr; return nullptr;
const ESM::Land* land = world->getStore().get<ESM::Land>().search(x, y); const ESM::Land* land = world->getStore().get<ESM::Land>().search(cellIndex.mX, cellIndex.mY);
if (!land) if (!land)
return nullptr; return nullptr;
osg::ref_ptr<ESMTerrain::LandObject> landObj(new ESMTerrain::LandObject(land, mLoadFlags)); osg::ref_ptr<ESMTerrain::LandObject> landObj(new ESMTerrain::LandObject(land, mLoadFlags));
mCache->addEntryToObjectCache(std::make_pair(x, y), landObj.get()); mCache->addEntryToObjectCache(cellIndex, landObj.get());
return landObj; return landObj;
} }
} }

View file

@ -15,7 +15,7 @@ namespace ESM
namespace MWRender namespace MWRender
{ {
class LandManager : public Resource::GenericResourceManager<std::pair<int, int>> class LandManager : public Resource::GenericResourceManager<ESM::ExteriorCellLocation>
{ {
public: public:
LandManager(int loadFlags); LandManager(int loadFlags);

View file

@ -9,6 +9,8 @@ namespace ESM
{ {
public: public:
virtual ~LandData() = default;
typedef signed char VNML; typedef signed char VNML;
virtual std::span<const float> getHeights() const = 0; virtual std::span<const float> getHeights() const = 0;

View file

@ -53,6 +53,12 @@ namespace ESM
{ {
int mX, mY; int mX, mY;
ESM::RefId mWorldspace; ESM::RefId mWorldspace;
ExteriorCellLocation()
: mX(0)
, mY(0)
, mWorldspace(ESM::Cell::sDefaultWorldspaceId)
{
}
ExteriorCellLocation(int x, int y, ESM::RefId worldspace) ExteriorCellLocation(int x, int y, ESM::RefId worldspace)
: mX(x) : mX(x)

View file

@ -6,6 +6,7 @@
#include <osg/Plane> #include <osg/Plane>
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
#include <components/esm4/loadland.hpp>
#include <components/misc/resourcehelpers.hpp> #include <components/misc/resourcehelpers.hpp>
#include <components/misc/strings/algorithm.hpp> #include <components/misc/strings/algorithm.hpp>
#include <components/vfs/manager.hpp> #include <components/vfs/manager.hpp>
@ -26,11 +27,21 @@ namespace ESMTerrain
{ {
} }
LandObject::LandObject(const ESM4::Land* land, int loadFlags)
: mLand(nullptr)
, mLoadFlags(0)
{
mData = std::make_unique<ESM4::Land>(*land);
}
LandObject::LandObject(const ESM::Land* land, int loadFlags) LandObject::LandObject(const ESM::Land* land, int loadFlags)
: mLand(land) : mLand(land)
, mLoadFlags(loadFlags) , mLoadFlags(loadFlags)
, mData()
{ {
mLand->loadData(mLoadFlags, &mData); auto esm3LandData = new ESM::Land::LandData;
mData.reset(esm3LandData);
mLand->loadData(mLoadFlags, esm3LandData);
} }
LandObject::LandObject(const LandObject& copy, const osg::CopyOp& copyop) LandObject::LandObject(const LandObject& copy, const osg::CopyOp& copyop)
@ -218,8 +229,8 @@ namespace ESMTerrain
const ESM::LandData* heightData = nullptr; const ESM::LandData* heightData = nullptr;
const ESM::LandData* normalData = nullptr; const ESM::LandData* normalData = nullptr;
const ESM::LandData* colourData = nullptr; const ESM::LandData* colourData = nullptr;
const int LandSize = ESM::Land::LAND_SIZE; const int LandSize = land ? land->getLandSize() : ESM::Land::LAND_SIZE;
const int LandSizeInUnits = Constants::CellSizeInUnits; const int LandSizeInUnits = land ? land->getRealSize() : Constants::CellSizeInUnits;
if (land) if (land)
{ {
heightData = land->getData(ESM::Land::DATA_VHGT); heightData = land->getData(ESM::Land::DATA_VHGT);

View file

@ -32,6 +32,8 @@ namespace ESMTerrain
public: public:
LandObject(); LandObject();
LandObject(const ESM::Land* land, int loadFlags); LandObject(const ESM::Land* land, int loadFlags);
LandObject(const ESM4::Land* land, int loadFlags);
LandObject(const LandObject& copy, const osg::CopyOp& copyop); LandObject(const LandObject& copy, const osg::CopyOp& copyop);
virtual ~LandObject(); virtual ~LandObject();
@ -39,17 +41,20 @@ namespace ESMTerrain
inline const ESM::LandData* getData(int flags) const inline const ESM::LandData* getData(int flags) const
{ {
if ((mData.mDataLoaded & flags) != flags) ESM::Land::LandData* esm3Land = dynamic_cast<ESM::Land::LandData*>(mData.get());
if (esm3Land && ((esm3Land->mDataLoaded & flags) != flags))
return nullptr; return nullptr;
return &mData; return mData.get();
} }
inline int getPlugin() const { return mLand->getPlugin(); } inline int getPlugin() const { return mLand->getPlugin(); }
inline int getLandSize() const { return mData->getLandSize(); }
inline int getRealSize() const { return mData->getSize(); }
private: private:
const ESM::Land* mLand; const ESM::Land* mLand;
int mLoadFlags; int mLoadFlags;
ESM::Land::LandData mData; std::unique_ptr<ESM::LandData> mData;
}; };
/// @brief Feeds data from ESM terrain records (ESM::Land, ESM::LandTexture) /// @brief Feeds data from ESM terrain records (ESM::Land, ESM::LandTexture)

View file

@ -35,7 +35,7 @@
#include <iostream> // FIXME: debug only #include <iostream> // FIXME: debug only
#include "reader.hpp" #include "reader.hpp"
//#include "writer.hpp" // #include "writer.hpp"
// overlap north // overlap north
// //
@ -232,6 +232,24 @@ void ESM4::Land::load(ESM4::Reader& reader)
// at least one of the quadrants do not have a base texture, return without setting the flag // at least one of the quadrants do not have a base texture, return without setting the flag
if (!missing) if (!missing)
mDataTypes |= LAND_VTEX; mDataTypes |= LAND_VTEX;
mMinHeight = -200000.f;
mMaxHeight = 200000.f;
float row_offset = mHeightMap.heightOffset;
for (int y = 0; y < VERTS_PER_SIDE; y++)
{
row_offset += mHeightMap.gradientData[y * VERTS_PER_SIDE];
mHeights[y * VERTS_PER_SIDE] = row_offset * HEIGHT_SCALE;
float colOffset = row_offset;
for (int x = 1; x < VERTS_PER_SIDE; x++)
{
colOffset += mHeightMap.gradientData[y * VERTS_PER_SIDE + x];
mHeights[x + y * VERTS_PER_SIDE] = colOffset * HEIGHT_SCALE;
}
}
} }
// void ESM4::Land::save(ESM4::Writer& writer) const // void ESM4::Land::save(ESM4::Writer& writer) const

View file

@ -33,11 +33,13 @@
#include "formid.hpp" #include "formid.hpp"
#include <components/esm/esmterrain.hpp>
namespace ESM4 namespace ESM4
{ {
class Reader; class Reader;
struct Land struct Land : public ESM::LandData
{ {
enum enum
{ {
@ -117,8 +119,10 @@ namespace ESM4
// FIXME: lazy loading not yet implemented // FIXME: lazy loading not yet implemented
int mDataTypes; // which data types are loaded int mDataTypes; // which data types are loaded
float mHeights[VERTS_PER_SIDE * VERTS_PER_SIDE]; // Float value of compressed Heightmap
float mMinHeight, mMaxHeight;
signed char mVertNorm[VERTS_PER_SIDE * VERTS_PER_SIDE * 3]; // from VNML subrecord signed char mVertNorm[VERTS_PER_SIDE * VERTS_PER_SIDE * 3]; // from VNML subrecord
signed char mVertColr[VERTS_PER_SIDE * VERTS_PER_SIDE * 3]; // from VCLR subrecord unsigned char mVertColr[VERTS_PER_SIDE * VERTS_PER_SIDE * 3]; // from VCLR subrecord
VHGT mHeightMap; VHGT mHeightMap;
Texture mTextures[4]; // 0 = bottom left, 1 = bottom right, 2 = top left, 3 = top right Texture mTextures[4]; // 0 = bottom left, 1 = bottom right, 2 = top left, 3 = top right
std::vector<FormId> mIds; // land texture (LTEX) formids std::vector<FormId> mIds; // land texture (LTEX) formids
@ -127,6 +131,15 @@ namespace ESM4
// void save(Writer& writer) const; // void save(Writer& writer) const;
// void blank(); // void blank();
std::span<const float> getHeights() const override { return mHeights; }
std::span<const VNML> getNormals() const override { return mVertNorm; }
std::span<const unsigned char> getColors() const override { return mVertColr; }
std::span<const uint16_t> getTextures() const override { return {}; }
float getSize() const override { return REAL_SIZE; }
float getMinHeight() const override { return mMinHeight; }
float getMaxHeight() const { return mMaxHeight; }
int getLandSize() const { return VERTS_PER_SIDE; }
}; };
} }