From cb8cdd88316d4afde10cc09a36abd1f7a134e6ed Mon Sep 17 00:00:00 2001 From: "florent.teppe" Date: Fri, 27 Jan 2023 14:07:50 +0100 Subject: [PATCH] ESM::CellVariant aans MWWorld:Cell now take reference in constructor: signals that nullptr isn't accepted. also applied other review comments. --- apps/openmw/mwclass/door.cpp | 2 +- apps/openmw/mwmechanics/aipackage.cpp | 2 +- apps/openmw/mwmechanics/aiwander.cpp | 2 +- apps/openmw/mwworld/cell.cpp | 59 +++++++------ apps/openmw/mwworld/cell.hpp | 4 +- apps/openmw/mwworld/scene.cpp | 88 ++++++++++---------- apps/openmw/mwworld/worldmodel.cpp | 14 ++-- components/detournavigator/navigatorimpl.cpp | 2 +- components/esm/esm3esm4bridge.cpp | 8 +- components/esm/esm3esm4bridge.hpp | 23 ++--- 10 files changed, 95 insertions(+), 109 deletions(-) diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 2035ac3507..0d27474428 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -307,7 +307,7 @@ namespace MWClass const osg::Vec2i index = MWWorld::positionToCellIndex(door.mRef.getDoorDest().pos[0], door.mRef.getDoorDest().pos[1]); const ESM::Cell* cell = world->getStore().get().search(index.x(), index.y()); - dest = world->getCellName(MWWorld::Cell(cell)); + dest = world->getCellName(MWWorld::Cell(*cell)); } return "#{sCell=" + std::string{ dest } + "}"; diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index 5abc99dac9..c966f704e9 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -418,7 +418,7 @@ bool MWMechanics::AiPackage::isNearInactiveCell(osg::Vec3f position) if (playerCell->isExterior()) { // get actor's distance from origin of center cell - Misc::CoordinateConverter(ESM::CellVariant(playerCell)).toLocal(position); + Misc::CoordinateConverter(ESM::CellVariant(*playerCell)).toLocal(position); // currently assumes 3 x 3 grid for exterior cells, with player at center cell. // AI shuts down actors before they reach edges of 3 x 3 grid. diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 3631cfb776..a421f7e8cd 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -839,7 +839,7 @@ namespace MWMechanics if (mDistance && storage.mCanWanderAlongPathGrid && !actor.getClass().isPureWaterCreature(actor)) { // get NPC's position in local (i.e. cell) coordinates - auto converter = Misc::CoordinateConverter(ESM::CellVariant(cell)); + auto converter = Misc::CoordinateConverter(ESM::CellVariant(*cell)); const osg::Vec3f npcPos = converter.toLocalVec3(mInitialActorPosition); // Find closest pathgrid point diff --git a/apps/openmw/mwworld/cell.cpp b/apps/openmw/mwworld/cell.cpp index 6fdc5c4041..48b40069b4 100644 --- a/apps/openmw/mwworld/cell.cpp +++ b/apps/openmw/mwworld/cell.cpp @@ -6,57 +6,56 @@ namespace MWWorld { - Cell::Cell(const ESM4::Cell* cell) + Cell::Cell(const ESM4::Cell& cell) : ESM::CellVariant(cell) { - assert(cell != nullptr); - mNameID = cell->mEditorId; - mDisplayname = cell->mFullName; - mGridPos.x() = cell->mX; - mGridPos.y() = cell->mY; + mNameID = cell.mEditorId; + mDisplayname = cell.mFullName; + mGridPos.x() = cell.mX; + mGridPos.y() = cell.mY; mRegion = ESM::RefId::sEmpty; // Unimplemented for now - mFlags.hasWater = (cell->mCellFlags & ESM4::CELL_HasWater) != 0; - mFlags.isExterior = !(cell->mCellFlags & ESM4::CELL_Interior); - mFlags.isQuasiExterior = (cell->mCellFlags & ESM4::CELL_QuasiExt) != 0; + mFlags.hasWater = (cell.mCellFlags & ESM4::CELL_HasWater) != 0; + mFlags.isExterior = !(cell.mCellFlags & ESM4::CELL_Interior); + mFlags.isQuasiExterior = (cell.mCellFlags & ESM4::CELL_QuasiExt) != 0; mFlags.noSleep = false; // No such notion in ESM4 - mCellId.mWorldspace = Misc::StringUtils::lowerCase(cell->mEditorId); + mCellId.mWorldspace = Misc::StringUtils::lowerCase(cell.mEditorId); mCellId.mWorld = ESM::RefId::sEmpty; - mCellId.mIndex.mX = cell->getGridX(); - mCellId.mIndex.mX = cell->getGridY(); + mCellId.mIndex.mX = cell.getGridX(); + mCellId.mIndex.mX = cell.getGridY(); mCellId.mPaged = isExterior(); - mMood.mAmbiantColor = cell->mLighting.ambient; - mMood.mFogColor = cell->mLighting.fogColor; - mMood.mDirectionalColor = cell->mLighting.directional; - mMood.mFogDensity = cell->mLighting.fogPower; + mMood.mAmbiantColor = cell.mLighting.ambient; + mMood.mFogColor = cell.mLighting.fogColor; + mMood.mDirectionalColor = cell.mLighting.directional; + mMood.mFogDensity = cell.mLighting.fogPower; } - Cell::Cell(const ESM::Cell* cell) + Cell::Cell(const ESM::Cell& cell) : ESM::CellVariant(cell) { assert(cell != nullptr); - mNameID = cell->mName; - mDisplayname = cell->mName; - mGridPos.x() = cell->getGridX(); - mGridPos.y() = cell->getGridY(); + mNameID = cell.mName; + mDisplayname = cell.mName; + mGridPos.x() = cell.getGridX(); + mGridPos.y() = cell.getGridY(); mRegion = ESM::RefId::sEmpty; // Unimplemented for now - mFlags.hasWater = (cell->mData.mFlags & ESM::Cell::HasWater) != 0; - mFlags.isExterior = !(cell->mData.mFlags & ESM::Cell::Interior); - mFlags.isQuasiExterior = (cell->mData.mFlags & ESM::Cell::QuasiEx) != 0; - mFlags.noSleep = (cell->mData.mFlags & ESM::Cell::NoSleep) != 0; + mFlags.hasWater = (cell.mData.mFlags & ESM::Cell::HasWater) != 0; + mFlags.isExterior = !(cell.mData.mFlags & ESM::Cell::Interior); + mFlags.isQuasiExterior = (cell.mData.mFlags & ESM::Cell::QuasiEx) != 0; + mFlags.noSleep = (cell.mData.mFlags & ESM::Cell::NoSleep) != 0; - mCellId = cell->getCellId(); + mCellId = cell.getCellId(); - mMood.mAmbiantColor = cell->mAmbi.mAmbient; - mMood.mFogColor = cell->mAmbi.mFog; - mMood.mDirectionalColor = cell->mAmbi.mSunlight; - mMood.mFogDensity = cell->mAmbi.mFogDensity; + mMood.mAmbiantColor = cell.mAmbi.mAmbient; + mMood.mFogColor = cell.mAmbi.mFog; + mMood.mDirectionalColor = cell.mAmbi.mSunlight; + mMood.mFogDensity = cell.mAmbi.mFogDensity; } std::string Cell::getDescription() const diff --git a/apps/openmw/mwworld/cell.hpp b/apps/openmw/mwworld/cell.hpp index 6761485f29..5067e223cf 100644 --- a/apps/openmw/mwworld/cell.hpp +++ b/apps/openmw/mwworld/cell.hpp @@ -30,8 +30,8 @@ namespace MWWorld }; public: - explicit Cell(const ESM4::Cell* cell); - explicit Cell(const ESM::Cell* cell); + explicit Cell(const ESM4::Cell& cell); + explicit Cell(const ESM::Cell& cell); int getGridX() const { return mGridPos.x(); } int getGridY() const { return mGridPos.y(); } diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 089428fd26..5772699e90 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -383,57 +383,57 @@ namespace MWWorld assert(mActiveCells.find(cell) == mActiveCells.end()); mActiveCells.insert(cell); - Log(Debug::Info) << "Loading cell " << cell->getCell()->getEditorName(); + Log(Debug::Info) << "Loading cell " << cell->getCell()->getDescription(); const int cellX = cell->getCell()->getGridX(); const int cellY = cell->getCell()->getGridY(); auto cellVariant = *cell->getCell(); + + if (cellVariant.isExterior()) + { + osg::ref_ptr land = mRendering.getLandManager()->getLand(cellX, cellY); + const ESM::Land::LandData* data = land ? land->getData(ESM::Land::DATA_VHGT) : nullptr; + const int verts = ESM::Land::LAND_SIZE; + const int worldsize = ESM::Land::REAL_SIZE; + if (data) + { + mPhysics->addHeightField( + data->mHeights, cellX, cellY, worldsize, verts, data->mMinHeight, data->mMaxHeight, land.get()); + } + else + { + static std::vector defaultHeight; + defaultHeight.resize(verts * verts, ESM::Land::DEFAULT_HEIGHT); + mPhysics->addHeightField(defaultHeight.data(), cellX, cellY, worldsize, verts, + ESM::Land::DEFAULT_HEIGHT, ESM::Land::DEFAULT_HEIGHT, land.get()); + } + if (const auto heightField = mPhysics->getHeightField(cellX, cellY)) + { + const osg::Vec2i cellPosition(cellX, cellY); + const btVector3& origin = heightField->getCollisionObject()->getWorldTransform().getOrigin(); + const osg::Vec3f shift(origin.x(), origin.y(), origin.z()); + const HeightfieldShape shape = [&]() -> HeightfieldShape { + if (data == nullptr) + { + return DetourNavigator::HeightfieldPlane{ static_cast(ESM::Land::DEFAULT_HEIGHT) }; + } + else + { + DetourNavigator::HeightfieldSurface heights; + heights.mHeights = data->mHeights; + heights.mSize = static_cast(ESM::Land::LAND_SIZE); + heights.mMinHeight = data->mMinHeight; + heights.mMaxHeight = data->mMaxHeight; + return heights; + } + }(); + mNavigator.addHeightfield(cellPosition, ESM::Land::REAL_SIZE, shape, navigatorUpdateGuard); + } + } + if (!cellVariant.isEsm4()) { auto cell3 = cellVariant.getEsm3(); - - if (cell3.isExterior()) - { - osg::ref_ptr land = mRendering.getLandManager()->getLand(cellX, cellY); - const ESM::Land::LandData* data = land ? land->getData(ESM::Land::DATA_VHGT) : nullptr; - const int verts = ESM::Land::LAND_SIZE; - const int worldsize = ESM::Land::REAL_SIZE; - if (data) - { - mPhysics->addHeightField( - data->mHeights, cellX, cellY, worldsize, verts, data->mMinHeight, data->mMaxHeight, land.get()); - } - else - { - static std::vector defaultHeight; - defaultHeight.resize(verts * verts, ESM::Land::DEFAULT_HEIGHT); - mPhysics->addHeightField(defaultHeight.data(), cellX, cellY, worldsize, verts, - ESM::Land::DEFAULT_HEIGHT, ESM::Land::DEFAULT_HEIGHT, land.get()); - } - if (const auto heightField = mPhysics->getHeightField(cellX, cellY)) - { - const osg::Vec2i cellPosition(cellX, cellY); - const btVector3& origin = heightField->getCollisionObject()->getWorldTransform().getOrigin(); - const osg::Vec3f shift(origin.x(), origin.y(), origin.z()); - const HeightfieldShape shape = [&]() -> HeightfieldShape { - if (data == nullptr) - { - return DetourNavigator::HeightfieldPlane{ static_cast(ESM::Land::DEFAULT_HEIGHT) }; - } - else - { - DetourNavigator::HeightfieldSurface heights; - heights.mHeights = data->mHeights; - heights.mSize = static_cast(ESM::Land::LAND_SIZE); - heights.mMinHeight = data->mMinHeight; - heights.mMaxHeight = data->mMaxHeight; - return heights; - } - }(); - mNavigator.addHeightfield(cellPosition, ESM::Land::REAL_SIZE, shape, navigatorUpdateGuard); - } - } - if (const auto pathgrid = mWorld.getStore().get().search(cell3)) mNavigator.addPathgrid(cell3, *pathgrid); } diff --git a/apps/openmw/mwworld/worldmodel.cpp b/apps/openmw/mwworld/worldmodel.cpp index 7b89e12ff4..c6d7d33ebb 100644 --- a/apps/openmw/mwworld/worldmodel.cpp +++ b/apps/openmw/mwworld/worldmodel.cpp @@ -67,7 +67,7 @@ MWWorld::CellStore* MWWorld::WorldModel::getCellStore(const ESM::Cell* cell) auto result = mInteriors.find(cell->mName); if (result == mInteriors.end()) - result = mInteriors.emplace(cell->mName, CellStore(MWWorld::Cell(cell), mStore, mReaders)).first; + result = mInteriors.emplace(cell->mName, CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first; return &result->second; } @@ -79,7 +79,7 @@ MWWorld::CellStore* MWWorld::WorldModel::getCellStore(const ESM::Cell* cell) if (result == mExteriors.end()) result = mExteriors .emplace(std::make_pair(cell->getGridX(), cell->getGridY()), - CellStore(MWWorld::Cell(cell), mStore, mReaders)) + CellStore(MWWorld::Cell(*cell), mStore, mReaders)) .first; return &result->second; @@ -186,7 +186,7 @@ MWWorld::CellStore* MWWorld::WorldModel::getExterior(int x, int y) cell = MWBase::Environment::get().getWorld()->createRecord(record); } - result = mExteriors.emplace(std::make_pair(x, y), CellStore(MWWorld::Cell(cell), mStore, mReaders)).first; + result = mExteriors.emplace(std::make_pair(x, y), CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first; } if (result->second.getState() != CellStore::State_Loaded) @@ -208,11 +208,11 @@ MWWorld::CellStore* MWWorld::WorldModel::getInterior(std::string_view name) if (!cell4) { const ESM::Cell* cell = mStore.get().find(name); - result = mInteriors.emplace(name, CellStore(MWWorld::Cell(cell), mStore, mReaders)).first; + result = mInteriors.emplace(name, CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first; } else { - result = mInteriors.emplace(name, CellStore(MWWorld::Cell(cell4), mStore, mReaders)).first; + result = mInteriors.emplace(name, CellStore(MWWorld::Cell(*cell4), mStore, mReaders)).first; } } @@ -265,12 +265,12 @@ const ESM::Cell* MWWorld::WorldModel::getESMCellByName(std::string_view name) ESM::CellVariant MWWorld::WorldModel::getCellByName(std::string_view name) { const ESM::Cell* cellEsm3 = getESMCellByName(name); - return ESM::CellVariant(cellEsm3); if (!cellEsm3) { const ESM4::Cell* cellESM4 = mStore.get().searchCellName(name); - return ESM::CellVariant(cellESM4); + return ESM::CellVariant(*cellESM4); } + return ESM::CellVariant(*cellEsm3); } MWWorld::CellStore* MWWorld::WorldModel::getCell(std::string_view name) diff --git a/components/detournavigator/navigatorimpl.cpp b/components/detournavigator/navigatorimpl.cpp index 542818a151..f064842f6b 100644 --- a/components/detournavigator/navigatorimpl.cpp +++ b/components/detournavigator/navigatorimpl.cpp @@ -134,7 +134,7 @@ namespace DetourNavigator void NavigatorImpl::addPathgrid(const ESM::Cell& cell, const ESM::Pathgrid& pathgrid) { - Misc::CoordinateConverter converter = Misc::CoordinateConverter(ESM::CellVariant(&cell)); + Misc::CoordinateConverter converter = Misc::CoordinateConverter(ESM::CellVariant(cell)); for (const auto& edge : pathgrid.mEdges) { const auto src = Misc::Convert::makeOsgVec3f(converter.toWorldPoint(pathgrid.mPoints[edge.mV0])); diff --git a/components/esm/esm3esm4bridge.cpp b/components/esm/esm3esm4bridge.cpp index f804f437bc..d38014e071 100644 --- a/components/esm/esm3esm4bridge.cpp +++ b/components/esm/esm3esm4bridge.cpp @@ -6,17 +6,13 @@ namespace ESM { const ESM4::Cell& CellVariant::getEsm4() const { - auto cell4 = std::get<0>(mVariant); - if (!cell4) - throw std::runtime_error("invalid variant acess"); + auto cell4 = std::get(mVariant); return *cell4; } const ESM::Cell& CellVariant::getEsm3() const { - auto cell = std::get<1>(mVariant); - if (!cell) - throw std::runtime_error("invalid variant acess"); + auto cell = std::get(mVariant); return *cell; } } diff --git a/components/esm/esm3esm4bridge.hpp b/components/esm/esm3esm4bridge.hpp index 6152b0e610..471ef96885 100644 --- a/components/esm/esm3esm4bridge.hpp +++ b/components/esm/esm3esm4bridge.hpp @@ -19,29 +19,20 @@ namespace ESM struct CellVariant { - std::variant mVariant; + private: + std::variant mVariant; - CellVariant() - : mVariant((void*)(nullptr)) + public: + explicit CellVariant(const ESM4::Cell& cell) + : mVariant(&cell) { } - explicit CellVariant(const ESM4::Cell* cell) - : mVariant(cell) + explicit CellVariant(const ESM::Cell& cell) + : mVariant(&cell) { } - explicit CellVariant(const ESM::Cell* cell) - : mVariant(cell) - { - } - - bool isValid() const - { - return std::holds_alternative(mVariant) - || std::holds_alternative(mVariant); - } - bool isEsm4() const { return std::holds_alternative(mVariant); } const ESM4::Cell& getEsm4() const;