diff --git a/apps/openmw/mwgui/mapwindow.cpp b/apps/openmw/mwgui/mapwindow.cpp index cedd09b4b2..691d096450 100644 --- a/apps/openmw/mwgui/mapwindow.cpp +++ b/apps/openmw/mwgui/mapwindow.cpp @@ -276,7 +276,10 @@ namespace MWGui if (!mInterior) { - cellIndex = ESM::positionToCellIndex(worldX, worldY); + ESM::ExteriorCellIndex cellPos = ESM::positionToCellIndex(worldX, worldY); + cellIndex.x() = cellPos.mX; + cellIndex.y() = cellPos.mY; + nX = (worldX - cellSize * cellIndex.x()) / cellSize; // Image space is -Y up, cells are Y up nY = 1 - (worldY - cellSize * cellIndex.y()) / cellSize; diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index 21d503aac8..4ad90547b5 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -125,11 +125,11 @@ namespace MWGui { std::string_view cellname = transport[i].mCellName; bool interior = true; - const osg::Vec2i cellIndex = ESM::positionToCellIndex(transport[i].mPos.pos[0], transport[i].mPos.pos[1]); + const ESM::ExteriorCellIndex cellIndex + = ESM::positionToCellIndex(transport[i].mPos.pos[0], transport[i].mPos.pos[1]); if (cellname.empty()) { - MWWorld::CellStore& cell = MWBase::Environment::get().getWorldModel()->getExterior( - ESM::ExteriorCellIndex(cellIndex.x(), cellIndex.y(), ESM::Cell::sDefaultWorldspaceId)); + MWWorld::CellStore& cell = MWBase::Environment::get().getWorldModel()->getExterior(cellIndex); cellname = MWBase::Environment::get().getWorld()->getCellName(&cell); interior = false; } @@ -192,8 +192,8 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); MWBase::Environment::get().getWindowManager()->fadeScreenOut(1); - osg::Vec2i posCell = ESM::positionToCellIndex(pos.pos[0], pos.pos[1]); - ESM::RefId cellId = ESM::Cell::generateIdForCell(!interior, cellname, posCell.x(), posCell.y()); + const ESM::ExteriorCellIndex posCell = ESM::positionToCellIndex(pos.pos[0], pos.pos[1]); + ESM::RefId cellId = ESM::Cell::generateIdForCell(!interior, cellname, posCell.mX, posCell.mY); // Teleports any followers, too. MWWorld::ActionTeleport action(cellId, pos, true); diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index e493f3d911..4bf1f148e5 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -400,9 +400,9 @@ namespace MWScript store = &worldModel->getCell(cellID); if (store->isExterior()) { - const osg::Vec2i cellIndex = ESM::positionToCellIndex(x, y); - store = &worldModel->getExterior( - ESM::ExteriorCellIndex(cellIndex.x(), cellIndex.y(), store->getCell()->getWorldSpace())); + const ESM::ExteriorCellIndex cellIndex + = ESM::positionToCellIndex(x, y, store->getCell()->getWorldSpace()); + store = &worldModel->getExterior(cellIndex); } } catch (std::exception&) @@ -416,9 +416,9 @@ namespace MWScript Log(Debug::Warning) << error; if (!isPlayer) return; - const osg::Vec2i cellIndex = ESM::positionToCellIndex(x, y); - store = &worldModel->getExterior( - ESM::ExteriorCellIndex(cellIndex.x(), cellIndex.y(), store->getCell()->getWorldSpace())); + const ESM::ExteriorCellIndex cellIndex + = ESM::positionToCellIndex(x, y, store->getCell()->getWorldSpace()); + store = &worldModel->getExterior(cellIndex); } if (store) { @@ -467,15 +467,15 @@ namespace MWScript { world->getPlayer().setTeleported(true); } - const osg::Vec2i cellIndex = ESM::positionToCellIndex(x, y); + const ESM::ExteriorCellIndex cellIndex + = ESM::positionToCellIndex(x, y, ESM::Cell::sDefaultWorldspaceId); // another morrowind oddity: player will be moved to the exterior cell at this location, // non-player actors will move within the cell they are in. MWWorld::Ptr base = ptr; if (isPlayer) { - MWWorld::CellStore* cell = &MWBase::Environment::get().getWorldModel()->getExterior( - ESM::ExteriorCellIndex(cellIndex.x(), cellIndex.y(), ESM::Cell::sDefaultWorldspaceId)); + MWWorld::CellStore* cell = &MWBase::Environment::get().getWorldModel()->getExterior(cellIndex); ptr = world->moveObject(ptr, cell, osg::Vec3(x, y, z)); } else @@ -568,9 +568,9 @@ namespace MWScript MWWorld::CellStore* store = nullptr; if (player.getCell()->isExterior()) { - const osg::Vec2i cellIndex = ESM::positionToCellIndex(x, y); - store = &MWBase::Environment::get().getWorldModel()->getExterior(ESM::ExteriorCellIndex( - cellIndex.x(), cellIndex.y(), player.getCell()->getCell()->getWorldSpace())); + const ESM::ExteriorCellIndex cellIndex + = ESM::positionToCellIndex(x, y, player.getCell()->getCell()->getWorldSpace()); + store = &MWBase::Environment::get().getWorldModel()->getExterior(cellIndex); } else store = player.getCell(); diff --git a/apps/openmw/mwworld/cellref.cpp b/apps/openmw/mwworld/cellref.cpp index 917d9e16d5..3e81ba1c37 100644 --- a/apps/openmw/mwworld/cellref.cpp +++ b/apps/openmw/mwworld/cellref.cpp @@ -88,8 +88,8 @@ namespace MWWorld } else { - const osg::Vec2i index = ESM::positionToCellIndex(ref.mDoorDest.pos[0], ref.mDoorDest.pos[1]); - return ESM::RefId::esm3ExteriorCell(index.x(), index.y()); + const auto cellPos = ESM::positionToCellIndex(ref.mDoorDest.pos[0], ref.mDoorDest.pos[1]); + return ESM::RefId::esm3ExteriorCell(cellPos.mX, cellPos.mY); } }; auto esm4Visit = [&](const ESM4::Reference& ref) -> ESM::RefId { diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 10145fbf17..08208b93b3 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -519,12 +519,13 @@ namespace MWWorld osg::Vec2 center = ESM::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); + float cellSize = ESM::getCellSize(worldspace); const float maxDistance = cellSize / 2 + mCellLoadingThreshold; // 1/2 cell size + threshold if (distance <= maxDistance) return *currentGridCenter; } - return ESM::positionToCellIndex(pos.x(), pos.y(), isEsm4Ext); + ESM::ExteriorCellIndex cellPos = ESM::positionToCellIndex(pos.x(), pos.y(), worldspace); + return { cellPos.mX, cellPos.mY }; } void Scene::playerMoved(const osg::Vec3f& pos) @@ -1162,8 +1163,7 @@ namespace MWWorld cellY = mCurrentGridCenter.y(); ESM::RefId extWorldspace = mWorld.getCurrentWorldspace(); - bool esm4Ext = ESM::isEsm4Ext(extWorldspace); - float cellSize = ESM::getCellSize(esm4Ext); + float cellSize = ESM::getCellSize(extWorldspace); for (int dx = -halfGridSizePlusOne; dx <= halfGridSizePlusOne; ++dx) { @@ -1283,10 +1283,8 @@ namespace MWWorld else { osg::Vec3f pos = dest.mPos.asVec3(); - const osg::Vec2i cellIndex = ESM::positionToCellIndex(pos.x(), pos.y()); - preloadCell(mWorld.getWorldModel().getExterior( - ESM::ExteriorCellIndex(cellIndex.x(), cellIndex.y(), extWorldspace)), - true); + const ESM::ExteriorCellIndex cellIndex = ESM::positionToCellIndex(pos.x(), pos.y(), extWorldspace); + preloadCell(mWorld.getWorldModel().getExterior(cellIndex), true); exteriorPositions.emplace_back(pos, gridCenterToBounds(getNewGridCenter(pos))); } } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 2d0700bd4f..d61c1b2334 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -379,8 +379,8 @@ namespace MWWorld pos.rot[1] = 0; pos.rot[2] = 0; - osg::Vec2i exteriorCellPos = ESM::positionToCellIndex(pos.pos[0], pos.pos[1]); - ESM::RefId cellId = ESM::RefId::esm3ExteriorCell(exteriorCellPos.x(), exteriorCellPos.y()); + ESM::ExteriorCellIndex exteriorCellPos = ESM::positionToCellIndex(pos.pos[0], pos.pos[1]); + ESM::RefId cellId = ESM::RefId::esm3ExteriorCell(exteriorCellPos.mX, exteriorCellPos.mY); mWorldScene->changeToExteriorCell(cellId, pos, true); } } @@ -1244,14 +1244,12 @@ namespace MWWorld MWWorld::Ptr World::moveObject(const Ptr& ptr, const osg::Vec3f& position, bool movePhysics, bool moveToActive) { - const osg::Vec2i index = ESM::positionToCellIndex(position.x(), position.y()); - CellStore* cell = ptr.getCell(); ESM::RefId worldspaceId = cell->isExterior() ? cell->getCell()->getWorldSpace() : ESM::Cell::sDefaultWorldspaceId; - CellStore* newCell = cell->isExterior() - ? &mWorldModel.getExterior(ESM::ExteriorCellIndex(index.x(), index.y(), worldspaceId)) - : nullptr; + const ESM::ExteriorCellIndex index = ESM::positionToCellIndex(position.x(), position.y(), worldspaceId); + + CellStore* newCell = cell->isExterior() ? &mWorldModel.getExterior(index) : nullptr; bool isCellActive = getPlayerPtr().isInCell() && getPlayerPtr().getCell()->isExterior() && (newCell && mWorldScene->isCellActive(*newCell)); @@ -1373,8 +1371,8 @@ namespace MWWorld && !(ptr.getClass().isPersistent(ptr) && ptr.getClass().getCreatureStats(ptr).isDeathAnimationFinished()); if (force || !ptr.getClass().isActor() || (!isFlying(ptr) && !swims && isActorCollisionEnabled(ptr))) { - bool esm4Ext = ptr.getCell()->isExterior() && ESM::isEsm4Ext(ptr.getCell()->getCell()->getWorldSpace()); - osg::Vec3f traced = mPhysics->traceDown(ptr, pos, ESM::getCellSize(esm4Ext)); + osg::Vec3f traced + = mPhysics->traceDown(ptr, pos, ESM::getCellSize(ptr.getCell()->getCell()->getWorldSpace())); pos.z() = std::min(pos.z(), traced.z()); } @@ -1409,9 +1407,9 @@ namespace MWWorld if (!mPhysics->castRay(pos, targetPos, MWPhysics::CollisionType_World | MWPhysics::CollisionType_Door).mHit) break; } - bool esm4Ext = actor.getCell()->isExterior() && ESM::isEsm4Ext(actor.getCell()->getCell()->getWorldSpace()); targetPos.z() += distance / 2.f; // move up a bit to get out from geometry, will snap down later - osg::Vec3f traced = mPhysics->traceDown(actor, targetPos, ESM::getCellSize(esm4Ext)); + osg::Vec3f traced + = mPhysics->traceDown(actor, targetPos, ESM::getCellSize(actor.getCell()->getCell()->getWorldSpace())); if (traced != pos) { esmPos.pos[0] = traced.x(); @@ -2048,9 +2046,9 @@ namespace MWWorld throw std::runtime_error("copyObjectToCell(): cannot copy object to null cell"); if (cell->isExterior()) { - const osg::Vec2i index = ESM::positionToCellIndex(pos.pos[0], pos.pos[1]); - cell = &mWorldModel.getExterior( - ESM::ExteriorCellIndex(index.x(), index.y(), cell->getCell()->getWorldSpace())); + const ESM::ExteriorCellIndex index + = ESM::positionToCellIndex(pos.pos[0], pos.pos[1], cell->getCell()->getWorldSpace()); + cell = &mWorldModel.getExterior(index); } MWWorld::Ptr dropped = object.getClass().copyToCell(object, *cell, pos, count); diff --git a/apps/openmw/mwworld/worldmodel.cpp b/apps/openmw/mwworld/worldmodel.cpp index 7491415630..dacbe63587 100644 --- a/apps/openmw/mwworld/worldmodel.cpp +++ b/apps/openmw/mwworld/worldmodel.cpp @@ -327,10 +327,11 @@ MWWorld::CellStore& MWWorld::WorldModel::getCellByPosition( { if (cellInSameWorldSpace && !cellInSameWorldSpace->isExterior()) return *cellInSameWorldSpace; - const osg::Vec2i cellIndex = ESM::positionToCellIndex(pos.x(), pos.y()); ESM::RefId exteriorWorldspace = cellInSameWorldSpace ? cellInSameWorldSpace->getCell()->getWorldSpace() : ESM::Cell::sDefaultWorldspaceId; - return getExterior(ESM::ExteriorCellIndex(cellIndex.x(), cellIndex.y(), exteriorWorldspace)); + const ESM::ExteriorCellIndex cellIndex = ESM::positionToCellIndex(pos.x(), pos.y(), exteriorWorldspace); + + return getExterior(cellIndex); } MWWorld::Ptr MWWorld::WorldModel::getPtr(const ESM::RefId& name, CellStore& cell) diff --git a/components/esm/util.cpp b/components/esm/util.cpp index 69277ad5a0..514472211b 100644 --- a/components/esm/util.cpp +++ b/components/esm/util.cpp @@ -2,7 +2,7 @@ osg::Vec2 ESM::indexToPosition(const ESM::ExteriorCellIndex& cellIndex, bool centre) { - const int cellSize = ESM::getCellSize(ESM::isEsm4Ext(cellIndex.mWorldspace)); + const int cellSize = ESM::getCellSize(cellIndex.mWorldspace); float x = static_cast(cellSize * cellIndex.mX); float y = static_cast(cellSize * cellIndex.mY); diff --git a/components/esm/util.hpp b/components/esm/util.hpp index 3ae244bd20..6a5c664ecc 100644 --- a/components/esm/util.hpp +++ b/components/esm/util.hpp @@ -72,20 +72,22 @@ namespace ESM } }; - static inline bool isEsm4Ext(ESM::RefId worldspaceId) + inline bool isEsm4Ext(ESM::RefId worldspaceId) { return worldspaceId != ESM::Cell::sDefaultWorldspaceId; } - static inline int getCellSize(bool isESM4Ext) + inline int getCellSize(ESM::RefId worldspaceId) { - return isESM4Ext ? Constants::ESM4CellSizeInUnits : Constants::CellSizeInUnits; + + return isEsm4Ext(worldspaceId) ? Constants::ESM4CellSizeInUnits : Constants::CellSizeInUnits; } - inline osg::Vec2i positionToCellIndex(float x, float y, bool esm4Ext = false) + inline ESM::ExteriorCellIndex positionToCellIndex( + float x, float y, ESM::RefId worldspaceId = ESM::Cell::sDefaultWorldspaceId) { - const float cellSize = esm4Ext ? Constants::ESM4CellSizeInUnits : Constants::CellSizeInUnits; - return { static_cast(std::floor(x / cellSize)), static_cast(std::floor(y / cellSize)) }; + const float cellSize = getCellSize(worldspaceId); + return { static_cast(std::floor(x / cellSize)), static_cast(std::floor(y / cellSize)), worldspaceId }; } osg::Vec2 indexToPosition(const ESM::ExteriorCellIndex& cellIndex, bool centre = false);