mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-06 00:55:50 +00:00
ESM4::Land loaded, added to store and to land objects
it does not work yet. Some things are displayed, but it looks all wrong.
This commit is contained in:
parent
fffcf52316
commit
c35c7b3640
@ -20,8 +20,6 @@ namespace MWRender
|
||||
|
||||
osg::ref_ptr<ESMTerrain::LandObject> LandManager::getLand(ESM::ExteriorCellLocation cellIndex)
|
||||
{
|
||||
if (ESM::isEsm4Ext(cellIndex.mWorldspace))
|
||||
return osg::ref_ptr<ESMTerrain::LandObject>(nullptr);
|
||||
osg::ref_ptr<osg::Object> obj = mCache->getRefFromObjectCache(cellIndex);
|
||||
if (obj)
|
||||
return static_cast<ESMTerrain::LandObject*>(obj.get());
|
||||
@ -30,12 +28,25 @@ namespace MWRender
|
||||
const auto world = MWBase::Environment::get().getWorld();
|
||||
if (!world)
|
||||
return nullptr;
|
||||
const ESM::Land* land = world->getStore().get<ESM::Land>().search(cellIndex.mX, cellIndex.mY);
|
||||
if (!land)
|
||||
return nullptr;
|
||||
osg::ref_ptr<ESMTerrain::LandObject> landObj(new ESMTerrain::LandObject(land, mLoadFlags));
|
||||
mCache->addEntryToObjectCache(cellIndex, landObj.get());
|
||||
return landObj;
|
||||
|
||||
if (ESM::isEsm4Ext(cellIndex.mWorldspace))
|
||||
{
|
||||
const ESM4::Land* land = world->getStore().get<ESM4::Land>().search(cellIndex);
|
||||
if (!land)
|
||||
return nullptr;
|
||||
osg::ref_ptr<ESMTerrain::LandObject> landObj(new ESMTerrain::LandObject(land, mLoadFlags));
|
||||
mCache->addEntryToObjectCache(cellIndex, landObj.get());
|
||||
return landObj;
|
||||
}
|
||||
else
|
||||
{
|
||||
const ESM::Land* land = world->getStore().get<ESM::Land>().search(cellIndex.mX, cellIndex.mY);
|
||||
if (!land)
|
||||
return nullptr;
|
||||
osg::ref_ptr<ESMTerrain::LandObject> landObj(new ESMTerrain::LandObject(land, mLoadFlags));
|
||||
mCache->addEntryToObjectCache(cellIndex, landObj.get());
|
||||
return landObj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <components/misc/algorithm.hpp>
|
||||
|
||||
#include <components/esm4/common.hpp>
|
||||
#include <components/esm4/loadland.hpp>
|
||||
#include <components/esm4/loadwrld.hpp>
|
||||
#include <components/esm4/reader.hpp>
|
||||
#include <components/esm4/readerutils.hpp>
|
||||
@ -385,6 +386,7 @@ namespace MWWorld
|
||||
{
|
||||
auto visitorRec = [this](ESM4::Reader& reader) { return ESMStoreImp::readRecord(reader, *this); };
|
||||
ESM4::ReaderUtils::readAll(reader, visitorRec, [](ESM4::Reader&) {});
|
||||
getWritable<ESM4::Land>().updateLandPositions(get<ESM4::Cell>());
|
||||
}
|
||||
|
||||
void ESMStore::setIdType(const ESM::RefId& id, ESM::RecNameInts type)
|
||||
|
@ -43,6 +43,7 @@ namespace ESM4
|
||||
struct MiscItem;
|
||||
struct Weapon;
|
||||
struct World;
|
||||
struct Land;
|
||||
}
|
||||
|
||||
namespace ESM
|
||||
@ -121,7 +122,7 @@ namespace MWWorld
|
||||
Store<ESM4::Static>, Store<ESM4::Cell>, Store<ESM4::Light>, Store<ESM4::Reference>, Store<ESM4::Activator>,
|
||||
Store<ESM4::Potion>, Store<ESM4::Ammunition>, Store<ESM4::Armor>, Store<ESM4::Book>, Store<ESM4::Clothing>,
|
||||
Store<ESM4::Container>, Store<ESM4::Door>, Store<ESM4::Ingredient>, Store<ESM4::MiscItem>,
|
||||
Store<ESM4::Weapon>, Store<ESM4::World>>;
|
||||
Store<ESM4::Weapon>, Store<ESM4::World>, Store<ESM4::Land>>;
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
|
@ -8,11 +8,14 @@
|
||||
#include <components/esm/records.hpp>
|
||||
#include <components/esm3/esmreader.hpp>
|
||||
#include <components/esm3/esmwriter.hpp>
|
||||
#include <components/esm4/loadland.hpp>
|
||||
#include <components/esm4/loadwrld.hpp>
|
||||
#include <components/loadinglistener/loadinglistener.hpp>
|
||||
#include <components/misc/rng.hpp>
|
||||
|
||||
#include <apps/openmw/mwworld/cell.hpp>
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwworld/cell.hpp"
|
||||
#include "../mwworld/worldimp.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -1189,6 +1192,29 @@ namespace MWWorld
|
||||
MWWorld::TypedDynamicStore<ESM4::Cell>::clearDynamic();
|
||||
}
|
||||
|
||||
void Store<ESM4::Land>::updateLandPositions(const Store<ESM4::Cell>& cells)
|
||||
{
|
||||
for (auto it : mStatic)
|
||||
{
|
||||
const ESM4::Cell* cell = cells.find(it.second.mCell);
|
||||
mLands[cell->getExteriorCellLocation()] = &it.second;
|
||||
}
|
||||
for (auto it : mDynamic)
|
||||
{
|
||||
const ESM4::Cell* cell = cells.find(it.second.mCell);
|
||||
mLands[cell->getExteriorCellLocation()] = &it.second;
|
||||
}
|
||||
}
|
||||
|
||||
const ESM4::Land* MWWorld::Store<ESM4::Land>::search(ESM::ExteriorCellLocation cellLocation) const
|
||||
{
|
||||
auto foundLand = mLands.find(cellLocation);
|
||||
if (foundLand == mLands.end())
|
||||
return nullptr;
|
||||
else
|
||||
return foundLand->second;
|
||||
}
|
||||
|
||||
// ESM4 Reference
|
||||
//=========================================================================
|
||||
|
||||
@ -1276,3 +1302,4 @@ template class MWWorld::TypedDynamicStore<ESM4::Reference, ESM::FormId>;
|
||||
template class MWWorld::TypedDynamicStore<ESM4::Cell>;
|
||||
template class MWWorld::TypedDynamicStore<ESM4::Weapon>;
|
||||
template class MWWorld::TypedDynamicStore<ESM4::World>;
|
||||
template class MWWorld::TypedDynamicStore<ESM4::Land>;
|
||||
|
@ -35,6 +35,11 @@ namespace ESM
|
||||
class ESMWriter;
|
||||
}
|
||||
|
||||
namespace ESM4
|
||||
{
|
||||
struct Land;
|
||||
}
|
||||
|
||||
namespace Loading
|
||||
{
|
||||
class Listener;
|
||||
@ -298,6 +303,17 @@ namespace MWWorld
|
||||
void clearDynamic() override;
|
||||
};
|
||||
|
||||
template <>
|
||||
class Store<ESM4::Land> : public TypedDynamicStore<ESM4::Land>
|
||||
{
|
||||
std::unordered_map<ESM::ExteriorCellLocation, const ESM4::Land*> mLands;
|
||||
|
||||
public:
|
||||
void updateLandPositions(const Store<ESM4::Cell>& cells);
|
||||
|
||||
const ESM4::Land* search(ESM::ExteriorCellLocation cellLocation) const;
|
||||
};
|
||||
|
||||
template <>
|
||||
class Store<ESM::Land> : public DynamicStore
|
||||
{
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <components/esm3/typetraits.hpp>
|
||||
#include <components/esm4/common.hpp>
|
||||
#include <components/esm4/loadcell.hpp>
|
||||
#include <components/esm4/loadland.hpp>
|
||||
#include <components/esm4/loadligh.hpp>
|
||||
#include <components/esm4/loadrefr.hpp>
|
||||
#include <components/esm4/loadstat.hpp>
|
||||
|
@ -37,11 +37,11 @@ namespace ESMTerrain
|
||||
LandObject::LandObject(const ESM::Land* land, int loadFlags)
|
||||
: mLand(land)
|
||||
, mLoadFlags(loadFlags)
|
||||
, mData()
|
||||
, mData(nullptr)
|
||||
{
|
||||
auto esm3LandData = new ESM::Land::LandData;
|
||||
mData.reset(esm3LandData);
|
||||
mLand->loadData(mLoadFlags, esm3LandData);
|
||||
std::unique_ptr<ESM::Land::LandData> esm3LandData = std::make_unique<ESM::Land::LandData>();
|
||||
mLand->loadData(mLoadFlags, esm3LandData.get());
|
||||
mData = std::move(esm3LandData);
|
||||
}
|
||||
|
||||
LandObject::LandObject(const LandObject& copy, const osg::CopyOp& copyop)
|
||||
@ -478,15 +478,16 @@ namespace ESMTerrain
|
||||
const ESM::LandData* data = land->getData(ESM::Land::DATA_VHGT);
|
||||
if (!data)
|
||||
return defaultHeight;
|
||||
const int landSize = data->getLandSize();
|
||||
|
||||
// Mostly lifted from Ogre::Terrain::getHeightAtTerrainPosition
|
||||
|
||||
// Normalized position in the cell
|
||||
float nX = (worldPos.x() - (cellX * Constants::CellSizeInUnits)) / cellSize;
|
||||
float nY = (worldPos.y() - (cellY * Constants::CellSizeInUnits)) / cellSize;
|
||||
float nX = (worldPos.x() - (cellX * cellSize)) / cellSize;
|
||||
float nY = (worldPos.y() - (cellY * cellSize)) / cellSize;
|
||||
|
||||
// get left / bottom points (rounded down)
|
||||
float factor = ESM::Land::LAND_SIZE - 1.0f;
|
||||
float factor = landSize - 1.0f;
|
||||
float invFactor = 1.0f / factor;
|
||||
|
||||
int startX = static_cast<int>(nX * factor);
|
||||
@ -494,8 +495,8 @@ namespace ESMTerrain
|
||||
int endX = startX + 1;
|
||||
int endY = startY + 1;
|
||||
|
||||
endX = std::min(endX, ESM::Land::LAND_SIZE - 1);
|
||||
endY = std::min(endY, ESM::Land::LAND_SIZE - 1);
|
||||
endX = std::min(endX, landSize - 1);
|
||||
endY = std::min(endY, landSize - 1);
|
||||
|
||||
// now get points in terrain space (effectively rounding them to boundaries)
|
||||
float startXTS = startX * invFactor;
|
||||
|
@ -41,6 +41,8 @@ namespace ESMTerrain
|
||||
|
||||
inline const ESM::LandData* getData(int flags) const
|
||||
{
|
||||
if (!mData)
|
||||
return nullptr;
|
||||
ESM::Land::LandData* esm3Land = dynamic_cast<ESM::Land::LandData*>(mData.get());
|
||||
if (esm3Land && ((esm3Land->mDataLoaded & flags) != flags))
|
||||
return nullptr;
|
||||
|
@ -36,6 +36,7 @@
|
||||
|
||||
#include <components/esm/defs.hpp>
|
||||
#include <components/esm/refid.hpp>
|
||||
#include <components/esm/util.hpp>
|
||||
#include <components/esm4/reader.hpp>
|
||||
|
||||
namespace ESM4
|
||||
@ -107,7 +108,10 @@ namespace ESM4
|
||||
int getGridX() const { return mX; }
|
||||
int getGridY() const { return mY; }
|
||||
bool isExterior() const { return !(mCellFlags & CELL_Interior); }
|
||||
|
||||
ESM::ExteriorCellLocation getExteriorCellLocation() const
|
||||
{
|
||||
return ESM::ExteriorCellLocation(mX, mY, isExterior() ? mParent : mId);
|
||||
}
|
||||
static float sInvalidWaterLevel;
|
||||
};
|
||||
}
|
||||
|
@ -54,11 +54,12 @@
|
||||
//
|
||||
void ESM4::Land::load(ESM4::Reader& reader)
|
||||
{
|
||||
mFormId = reader.hdr().record.getFormId();
|
||||
reader.adjustFormId(mFormId);
|
||||
ESM::FormId formId = reader.hdr().record.getFormId();
|
||||
reader.adjustFormId(formId);
|
||||
mId = ESM::RefId::formIdRefId(formId);
|
||||
mFlags = reader.hdr().record.flags;
|
||||
mDataTypes = 0;
|
||||
|
||||
mCell = ESM::RefId::formIdRefId(reader.currCell());
|
||||
TxtLayer layer;
|
||||
std::int8_t currentAddQuad = -1; // for VTXT following ATXT
|
||||
|
||||
@ -252,6 +253,29 @@ void ESM4::Land::load(ESM4::Reader& reader)
|
||||
}
|
||||
}
|
||||
|
||||
ESM4::Land::Land(const Land& Other)
|
||||
{
|
||||
mId = Other.mId;
|
||||
mCell = Other.mCell;
|
||||
for (int i = 0; i < VERTS_PER_SIDE * VERTS_PER_SIDE; i++)
|
||||
{
|
||||
mHeights[i] = Other.mHeights[i];
|
||||
}
|
||||
for (int i = 0; i < VERTS_PER_SIDE * VERTS_PER_SIDE * 3; i++)
|
||||
{
|
||||
mVertNorm[i] = Other.mVertNorm[i];
|
||||
mVertColr[i] = Other.mVertColr[i];
|
||||
}
|
||||
mMinHeight = Other.mMinHeight;
|
||||
mMaxHeight = Other.mMaxHeight;
|
||||
}
|
||||
|
||||
std::span<const uint16_t> ESM4::Land::getTextures() const
|
||||
{
|
||||
static uint16_t textureArray[16 * 16] = {};
|
||||
return textureArray;
|
||||
}
|
||||
|
||||
// void ESM4::Land::save(ESM4::Writer& writer) const
|
||||
//{
|
||||
// }
|
||||
|
@ -33,7 +33,9 @@
|
||||
|
||||
#include "formid.hpp"
|
||||
|
||||
#include <components/esm/defs.hpp>
|
||||
#include <components/esm/esmterrain.hpp>
|
||||
#include <components/esm/refid.hpp>
|
||||
|
||||
namespace ESM4
|
||||
{
|
||||
@ -111,7 +113,7 @@ namespace ESM4
|
||||
std::vector<TxtLayer> layers;
|
||||
};
|
||||
|
||||
FormId mFormId; // from the header
|
||||
ESM::RefId mId; // from the header
|
||||
std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
|
||||
|
||||
std::uint32_t mLandFlags; // from DATA subrecord
|
||||
@ -126,16 +128,19 @@ namespace ESM4
|
||||
VHGT mHeightMap;
|
||||
Texture mTextures[4]; // 0 = bottom left, 1 = bottom right, 2 = top left, 3 = top right
|
||||
std::vector<FormId> mIds; // land texture (LTEX) formids
|
||||
|
||||
ESM::RefId mCell;
|
||||
void load(Reader& reader);
|
||||
Land() = default;
|
||||
Land(const Land& Other);
|
||||
// void save(Writer& writer) const;
|
||||
|
||||
// void blank();
|
||||
static constexpr ESM::RecNameInts sRecordId = ESM::REC_LAND4;
|
||||
|
||||
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 {}; }
|
||||
std::span<const uint16_t> getTextures() const override;
|
||||
float getSize() const override { return REAL_SIZE; }
|
||||
float getMinHeight() const override { return mMinHeight; }
|
||||
float getMaxHeight() const { return mMaxHeight; }
|
||||
|
@ -262,7 +262,7 @@ namespace Terrain
|
||||
auto chunkBorder = CellBorder::createBorderGeometry(center.x() - size / 2.f, center.y() - size / 2.f, size,
|
||||
mStorage, mSceneManager, mNodeMask, mWorldspace, 5.f, { 1, 0, 0, 0 });
|
||||
osg::ref_ptr<SceneUtil::PositionAttitudeTransform> pat = new SceneUtil::PositionAttitudeTransform;
|
||||
pat->setPosition(-center * Constants::CellSizeInUnits);
|
||||
pat->setPosition(-center * ESM::getCellSize(mWorldspace));
|
||||
pat->addChild(chunkBorder);
|
||||
return pat;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user