diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index f28d6f8f7c..ffb6be9958 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -517,8 +517,8 @@ namespace MWWorld 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())); - const float maxDistance - = Constants::CellSizeInUnits / 2 + mCellLoadingThreshold; // 1/2 cell size + threshold + float cellSize = Constants::getCellSize(isEsm4Ext); + const float maxDistance = cellSize / 2 + mCellLoadingThreshold; // 1/2 cell size + threshold if (distance <= maxDistance) return *currentGridCenter; } @@ -1166,6 +1166,8 @@ namespace MWWorld float centerX, centerY; mWorld.indexToPosition(cellX, cellY, centerX, centerY, true); + float cellSize = mWorld.getCurrentCellSize(); + bool esm4Ext = cellSize == Constants::ESM4CellSizeInUnits; for (int dx = -halfGridSizePlusOne; dx <= halfGridSizePlusOne; ++dx) { @@ -1176,15 +1178,14 @@ namespace MWWorld 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); + mWorld.indexToPosition(cellX + dx, cellY + dy, thisCellCenterX, thisCellCenterY, true, esm4Ext); float dist = std::max(std::abs(thisCellCenterX - playerPos.x()), std::abs(thisCellCenterY - playerPos.y())); dist = std::min(dist, std::max( std::abs(thisCellCenterX - predictedPos.x()), std::abs(thisCellCenterY - predictedPos.y()))); - float loadDist = Constants::CellSizeInUnits / 2 + Constants::CellSizeInUnits - mCellLoadingThreshold - + mPreloadDistance; + float loadDist = cellSize / 2 + cellSize - mCellLoadingThreshold + mPreloadDistance; if (dist < loadDist) preloadCell(mWorld.getWorldModel().getExterior( diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 78afca2766..9eeddc32e4 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1374,7 +1374,9 @@ namespace MWWorld && !(ptr.getClass().isPersistent(ptr) && ptr.getClass().getCreatureStats(ptr).isDeathAnimationFinished()); if (force || !ptr.getClass().isActor() || (!isFlying(ptr) && !swims && isActorCollisionEnabled(ptr))) { - osg::Vec3f traced = mPhysics->traceDown(ptr, pos, Constants::CellSizeInUnits); + bool esm4Ext = ptr.getCell()->isExterior() + && ptr.getCell()->getCell()->getWorldSpace() != ESM::Cell::sDefaultWorldspaceId; + osg::Vec3f traced = mPhysics->traceDown(ptr, pos, Constants::getCellSize(esm4Ext)); pos.z() = std::min(pos.z(), traced.z()); } @@ -1409,9 +1411,10 @@ namespace MWWorld if (!mPhysics->castRay(pos, targetPos, MWPhysics::CollisionType_World | MWPhysics::CollisionType_Door).mHit) break; } - + bool esm4Ext = actor.getCell()->isExterior() + && actor.getCell()->getCell()->getWorldSpace() != ESM::Cell::sDefaultWorldspaceId; 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, Constants::CellSizeInUnits); + osg::Vec3f traced = mPhysics->traceDown(actor, targetPos, Constants::getCellSize(esm4Ext)); if (traced != pos) { esmPos.pos[0] = traced.x(); @@ -1497,7 +1500,7 @@ namespace MWWorld void World::indexToPosition(int cellX, int cellY, float& x, float& y, bool centre, bool esm4Ext) const { - const int cellSize = esm4Ext ? Constants::ESM4CellSizeInUnits : Constants::CellSizeInUnits; + const int cellSize = Constants::getCellSize(esm4Ext); x = static_cast(cellSize * cellX); y = static_cast(cellSize * cellY); @@ -1907,6 +1910,14 @@ namespace MWWorld return false; } + float World::getCurrentCellSize() const + { + const CellStore* cellStore = mWorldScene->getCurrentCell(); + if (cellStore) + return Constants::getCellSize(cellStore->getCell()->isEsm4()); + return Constants::getCellSize(false); + } + int World::getCurrentWeather() const { return mWeatherManager->getWeatherID(); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 83268ddfc5..306372dbb1 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -246,6 +246,8 @@ namespace MWWorld bool isCellQuasiExterior() const override; + float getCurrentCellSize() const; + void getDoorMarkers(MWWorld::CellStore& cell, std::vector& out) override; ///< get a list of teleport door markers for a given cell, to be displayed on the local map diff --git a/components/misc/constants.hpp b/components/misc/constants.hpp index 545db87094..07ea0b6ca8 100644 --- a/components/misc/constants.hpp +++ b/components/misc/constants.hpp @@ -24,6 +24,10 @@ namespace Constants // Size of one exterior cell in game units constexpr int CellSizeInUnits = 8192; constexpr int ESM4CellSizeInUnits = 4096; + static inline int getCellSize(bool isESM4Ext) + { + return isESM4Ext ? ESM4CellSizeInUnits : CellSizeInUnits; + } // Size of active cell grid in cells (it is a square with the (2 * CellGridRadius + 1) cells side) constexpr int CellGridRadius = 1;