From f261f59809e325a7662e068253d0abff8206b5b7 Mon Sep 17 00:00:00 2001 From: "florent.teppe" Date: Tue, 9 May 2023 23:44:57 +0200 Subject: [PATCH] World::indexToPosition is modified to be less error prone. --- apps/openmw/mwbase/world.hpp | 4 ++-- apps/openmw/mwscript/cellextensions.cpp | 5 ++++- apps/openmw/mwstate/statemanagerimp.cpp | 11 +++++---- apps/openmw/mwworld/scene.cpp | 30 +++++++++++++------------ apps/openmw/mwworld/worldimp.cpp | 14 +++++++----- apps/openmw/mwworld/worldimp.hpp | 3 +-- 6 files changed, 36 insertions(+), 31 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index a8bec3b1a5..79f709e224 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -55,6 +55,7 @@ namespace ESM struct ItemLevList; struct TimeStamp; class RefId; + struct ExteriorCellIndex; } namespace MWPhysics @@ -312,8 +313,7 @@ namespace MWBase /// relative to \a referenceObject (but the object may be placed somewhere else if the wanted location is /// obstructed). - virtual void indexToPosition( - int cellX, int cellY, float& x, float& y, bool centre = false, bool esm4Exterior = false) const = 0; + virtual osg::Vec2 indexToPosition(const ESM::ExteriorCellIndex& cellIndex, bool centre = false) const = 0; ///< Convert cell numbers to position. virtual void queueMovement(const MWWorld::Ptr& ptr, const osg::Vec3f& velocity) = 0; diff --git a/apps/openmw/mwscript/cellextensions.cpp b/apps/openmw/mwscript/cellextensions.cpp index 1c212d5f8c..bd7592561c 100644 --- a/apps/openmw/mwscript/cellextensions.cpp +++ b/apps/openmw/mwscript/cellextensions.cpp @@ -123,7 +123,10 @@ namespace MWScript MWBase::World* world = MWBase::Environment::get().getWorld(); const MWWorld::Ptr playerPtr = world->getPlayerPtr(); - world->indexToPosition(x, y, pos.pos[0], pos.pos[1], true); + osg::Vec2 posFromIndex + = world->indexToPosition(ESM::ExteriorCellIndex(x, y, ESM::Cell::sDefaultWorldspaceId), true); + pos.pos[0] = posFromIndex.x(); + pos.pos[1] = posFromIndex.y(); pos.pos[2] = 0; pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index 3d31da8263..7a544e9016 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -563,13 +563,12 @@ void MWState::StateManager::loadGame(const Character* character, const std::file { // Cell no longer exists (i.e. changed game files), choose a default cell Log(Debug::Warning) << "Warning: Player character's cell no longer exists, changing to the default cell"; - MWWorld::CellStore& cell = MWBase::Environment::get().getWorldModel()->getExterior( - ESM::ExteriorCellIndex(0, 0, ESM::Cell::sDefaultWorldspaceId)); - float x, y; - MWBase::Environment::get().getWorld()->indexToPosition(0, 0, x, y, false); + ESM::ExteriorCellIndex cellIndex(0, 0, ESM::Cell::sDefaultWorldspaceId); + MWWorld::CellStore& cell = MWBase::Environment::get().getWorldModel()->getExterior(cellIndex); + osg::Vec2 posFromIndex = MWBase::Environment::get().getWorld()->indexToPosition(cellIndex, false); ESM::Position pos; - pos.pos[0] = x; - pos.pos[1] = y; + pos.pos[0] = posFromIndex.x(); + pos.pos[1] = posFromIndex.y(); pos.pos[2] = 0; // should be adjusted automatically (adjustPlayerPos=true) pos.rot[0] = 0; pos.rot[1] = 0; diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 3cdf36d86e..5dc35ef2d3 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -511,12 +511,15 @@ namespace MWWorld osg::Vec2i Scene::getNewGridCenter(const osg::Vec3f& pos, const osg::Vec2i* currentGridCenter) const { - bool isEsm4Ext = mCurrentCell && ESM::isEsm4Ext(mCurrentCell->getCell()->getWorldSpace()); + ESM::RefId worldspace + = mCurrentCell ? mCurrentCell->getCell()->getWorldSpace() : ESM::Cell::sDefaultWorldspaceId; + bool isEsm4Ext = ESM::isEsm4Ext(worldspace); + if (currentGridCenter) { - float centerX, centerY; - mWorld.indexToPosition(currentGridCenter->x(), currentGridCenter->y(), centerX, centerY, true, isEsm4Ext); - float distance = std::max(std::abs(centerX - pos.x()), std::abs(centerY - pos.y())); + osg::Vec2 center = mWorld.indexToPosition( + ESM::ExteriorCellIndex(currentGridCenter->x(), currentGridCenter->y(), worldspace), true); + float distance = std::max(std::abs(center.x() - pos.x()), std::abs(center.y() - pos.y())); float cellSize = ESM::getCellSize(isEsm4Ext); const float maxDistance = cellSize / 2 + mCellLoadingThreshold; // 1/2 cell size + threshold if (distance <= maxDistance) @@ -1163,11 +1166,10 @@ namespace MWWorld int cellX, cellY; cellX = mCurrentGridCenter.x(); cellY = mCurrentGridCenter.y(); - - float centerX, centerY; - mWorld.indexToPosition(cellX, cellY, centerX, centerY, true); - ESM::RefId extWorldspace = mWorld.getCurrentWorldspace(); + + osg::Vec2 center = mWorld.indexToPosition(ESM::ExteriorCellIndex(cellX, cellY, extWorldspace), true); + bool esm4Ext = ESM::isEsm4Ext(extWorldspace); float cellSize = ESM::getCellSize(esm4Ext); @@ -1179,14 +1181,14 @@ namespace MWWorld && dx != -halfGridSizePlusOne) continue; // only care about the outer (not yet loaded) part of the grid - float thisCellCenterX, thisCellCenterY; - mWorld.indexToPosition(cellX + dx, cellY + dy, thisCellCenterX, thisCellCenterY, true, esm4Ext); + osg::Vec2 thisCellCenter + = mWorld.indexToPosition(ESM::ExteriorCellIndex(cellX + dx, cellY + dy, extWorldspace), true); - float dist - = std::max(std::abs(thisCellCenterX - playerPos.x()), std::abs(thisCellCenterY - playerPos.y())); + float dist = std::max( + std::abs(thisCellCenter.x() - playerPos.x()), std::abs(thisCellCenter.y() - playerPos.y())); dist = std::min(dist, - std::max( - std::abs(thisCellCenterX - predictedPos.x()), std::abs(thisCellCenterY - predictedPos.y()))); + std::max(std::abs(thisCellCenter.x() - predictedPos.x()), + std::abs(thisCellCenter.y() - predictedPos.y()))); float loadDist = cellSize / 2 + cellSize - mCellLoadingThreshold + mPreloadDistance; if (dist < loadDist) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 6ba7659f39..5d889f5a44 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1496,18 +1496,19 @@ namespace MWWorld return placed; } - void World::indexToPosition(int cellX, int cellY, float& x, float& y, bool centre, bool esm4Ext) const + osg::Vec2 World::indexToPosition(const ESM::ExteriorCellIndex& cellIndex, bool centre) const { - const int cellSize = ESM::getCellSize(esm4Ext); + const int cellSize = ESM::getCellSize(ESM::isEsm4Ext(cellIndex.mWorldspace)); - x = static_cast(cellSize * cellX); - y = static_cast(cellSize * cellY); + float x = static_cast(cellSize * cellIndex.mX); + float y = static_cast(cellSize * cellIndex.mY); if (centre) { x += cellSize / 2; y += cellSize / 2; } + return osg::Vec2(x, y); } void World::queueMovement(const Ptr& ptr, const osg::Vec3f& velocity) @@ -2760,8 +2761,9 @@ namespace MWWorld { int x = ext->getGridX(); int y = ext->getGridY(); - bool esm4Ext = ESM::isEsm4Ext(ext->getWorldSpace()); - indexToPosition(x, y, pos.pos[0], pos.pos[1], true, esm4Ext); + osg::Vec2 posFromIndex = indexToPosition(ESM::ExteriorCellIndex(x, y, ext->getWorldSpace()), true); + pos.pos[0] = posFromIndex.x(); + pos.pos[1] = posFromIndex.y(); // Note: Z pos will be adjusted by adjustPosition later pos.pos[2] = 0; diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 7189c8b4be..675ccd5b34 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -400,8 +400,7 @@ namespace MWWorld float getMaxActivationDistance() const override; - void indexToPosition( - int cellX, int cellY, float& x, float& y, bool centre = false, bool esm4Exterior = false) const override; + osg::Vec2 indexToPosition(const ESM::ExteriorCellIndex& cellIndex, bool centre = false) const override; ///< Convert cell numbers to position. void queueMovement(const Ptr& ptr, const osg::Vec3f& velocity) override;