diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index e3ad2bd996..f16b99f8eb 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -242,7 +242,7 @@ bool OMW::Engine::frame(float frametime) mScriptManager->getGlobalScripts().run(); } - mWorld->markCellAsUnchanged(); + mWorld->getWorldScene().markCellAsUnchanged(); } if (!guiActive) @@ -772,6 +772,8 @@ void OMW::Engine::prepareEngine() mWorld->setupPlayer(); mWorld->setRandomSeed(mRandomSeed); mEnvironment.setWorld(*mWorld); + mEnvironment.setWorldModel(mWorld->getWorldModel()); + mEnvironment.setWorldScene(mWorld->getWorldScene()); mWindowManager->setStore(mWorld->getStore()); mWindowManager->initUI(); diff --git a/apps/openmw/mwbase/environment.hpp b/apps/openmw/mwbase/environment.hpp index 0c159d27cd..581b587d00 100644 --- a/apps/openmw/mwbase/environment.hpp +++ b/apps/openmw/mwbase/environment.hpp @@ -15,6 +15,12 @@ namespace l10n class Manager; } +namespace MWWorld +{ + class Cells; + class Scene; +} + namespace MWBase { class World; @@ -37,6 +43,8 @@ namespace MWBase static Environment* sThis; World* mWorld = nullptr; + MWWorld::Cells* mWorldModel = nullptr; // TODO: rename Cells -> WorldModel + MWWorld::Scene* mWorldScene = nullptr; SoundManager* mSoundManager = nullptr; ScriptManager* mScriptManager = nullptr; WindowManager* mWindowManager = nullptr; @@ -61,6 +69,8 @@ namespace MWBase Environment& operator=(const Environment&) = delete; void setWorld(World& value) { mWorld = &value; } + void setWorldModel(MWWorld::Cells& value) { mWorldModel = &value; } + void setWorldScene(MWWorld::Scene& value) { mWorldScene = &value; } void setSoundManager(SoundManager& value) { mSoundManager = &value; } @@ -85,6 +95,8 @@ namespace MWBase void setL10nManager(l10n::Manager& value) { mL10nManager = &value; } Misc::NotNullPtr getWorld() const { return mWorld; } + Misc::NotNullPtr getWorldModel() const { return mWorldModel; } + Misc::NotNullPtr getWorldScene() const { return mWorldScene; } Misc::NotNullPtr getSoundManager() const { return mSoundManager; } diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 67e8b55db4..15484fc262 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -133,17 +133,6 @@ namespace MWBase virtual void readRecord(ESM::ESMReader& reader, uint32_t type, const std::map& contentFileMap) = 0; - virtual MWWorld::CellStore* getExterior(int x, int y) = 0; - - virtual MWWorld::CellStore* getInterior(std::string_view name) = 0; - - virtual MWWorld::CellStore* getCell(const ESM::CellId& id) = 0; - - virtual bool isCellActive(MWWorld::CellStore* cell) const = 0; - - virtual void testExteriorCells() = 0; - virtual void testInteriorCells() = 0; - virtual void useDeathCamera() = 0; virtual void setWaterHeight(const float height) = 0; @@ -162,9 +151,6 @@ namespace MWBase virtual MWWorld::LocalScripts& getLocalScripts() = 0; - virtual bool hasCellChanged() const = 0; - ///< Has the set of active cells changed, since the last frame? - virtual bool isCellExterior() const = 0; virtual bool isCellQuasiExterior() const = 0; @@ -279,8 +265,6 @@ namespace MWBase virtual const ESM::Cell* getExterior(std::string_view cellName) const = 0; ///< Return a cell matching the given name or a 0-pointer, if there is no such cell. - virtual void markCellAsUnchanged() = 0; - virtual MWWorld::Ptr getFacedObject() = 0; ///< Return pointer to the object the player is looking at, if it is within activation range @@ -349,14 +333,6 @@ namespace MWBase virtual const MWPhysics::RayCastingInterface* getRayCasting() const = 0; - virtual bool castRay(float x1, float y1, float z1, float x2, float y2, float z2, int mask) = 0; - ///< cast a Ray and return true if there is an object in the ray path. - - virtual bool castRay(float x1, float y1, float z1, float x2, float y2, float z2) = 0; - - virtual bool castRay(const osg::Vec3f& from, const osg::Vec3f& to, int mask, const MWWorld::ConstPtr& ignore) - = 0; - virtual bool castRenderingRay(MWPhysics::RayCastingResult& res, const osg::Vec3f& from, const osg::Vec3f& to, bool ignorePlayer, bool ignoreActors) = 0; diff --git a/apps/openmw/mwgui/mapwindow.cpp b/apps/openmw/mwgui/mapwindow.cpp index fe728b3965..83ec58d43e 100644 --- a/apps/openmw/mwgui/mapwindow.cpp +++ b/apps/openmw/mwgui/mapwindow.cpp @@ -22,6 +22,7 @@ #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" +#include "../mwworld/cells.hpp" #include "../mwworld/cellstore.hpp" #include "../mwworld/cellutils.hpp" #include "../mwworld/esmstore.hpp" @@ -586,7 +587,8 @@ namespace MWGui if (!entry.mMapTexture) { if (!mInterior) - requestMapRender(MWBase::Environment::get().getWorld()->getExterior(entry.mCellX, entry.mCellY)); + requestMapRender( + MWBase::Environment::get().getWorldModel()->getExterior(entry.mCellX, entry.mCellY)); osg::ref_ptr texture = mLocalMapRender->getMapTexture(entry.mCellX, entry.mCellY); if (texture) @@ -624,6 +626,7 @@ namespace MWGui { std::vector doors; MWBase::World* world = MWBase::Environment::get().getWorld(); + MWWorld::Cells* worldModel = MWBase::Environment::get().getWorldModel(); mDoorMarkersToRecycle.insert( mDoorMarkersToRecycle.end(), mInteriorDoorMarkerWidgets.begin(), mInteriorDoorMarkerWidgets.end()); @@ -634,7 +637,7 @@ namespace MWGui for (MyGUI::Widget* widget : mExteriorDoorMarkerWidgets) widget->setVisible(false); - MWWorld::CellStore* cell = world->getInterior(mPrefix); + MWWorld::CellStore* cell = worldModel->getInterior(mPrefix); world->getDoorMarkers(cell, doors); } else @@ -642,7 +645,7 @@ namespace MWGui for (MapEntry& entry : mMaps) { if (!entry.mMapTexture && !widgetCropped(entry.mMapWidget, mLocalMap)) - world->getDoorMarkers(world->getExterior(entry.mCellX, entry.mCellY), doors); + world->getDoorMarkers(worldModel->getExterior(entry.mCellX, entry.mCellY), doors); } if (doors.empty()) return; diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index 5fea9b019b..0df14b7801 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -13,6 +13,7 @@ #include "../mwbase/world.hpp" #include "../mwworld/actionteleport.hpp" +#include "../mwworld/cells.hpp" #include "../mwworld/cellstore.hpp" #include "../mwworld/cellutils.hpp" #include "../mwworld/class.hpp" @@ -127,7 +128,7 @@ namespace MWGui if (cellname.empty()) { MWWorld::CellStore* cell - = MWBase::Environment::get().getWorld()->getExterior(cellIndex.x(), cellIndex.y()); + = MWBase::Environment::get().getWorldModel()->getExterior(cellIndex.x(), cellIndex.y()); cellname = MWBase::Environment::get().getWorld()->getCellName(cell); interior = false; } diff --git a/apps/openmw/mwlua/luamanagerimp.cpp b/apps/openmw/mwlua/luamanagerimp.cpp index a6e55ed3e9..d17d420eee 100644 --- a/apps/openmw/mwlua/luamanagerimp.cpp +++ b/apps/openmw/mwlua/luamanagerimp.cpp @@ -27,6 +27,7 @@ #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" #include "../mwworld/ptr.hpp" +#include "../mwworld/scene.hpp" #include "debugbindings.hpp" #include "luabindings.hpp" @@ -402,7 +403,7 @@ namespace MWLua { localScripts = createLocalScripts(ptr); localScripts->addAutoStartedScripts(); - if (ptr.isInCell() && MWBase::Environment::get().getWorld()->isCellActive(ptr.getCell())) + if (ptr.isInCell() && MWBase::Environment::get().getWorldScene()->isCellActive(*ptr.getCell())) mActiveLocalScripts.insert(localScripts); } localScripts->addCustomScript(scriptId); diff --git a/apps/openmw/mwlua/worldview.cpp b/apps/openmw/mwlua/worldview.cpp index 49b28226d2..6435c35415 100644 --- a/apps/openmw/mwlua/worldview.cpp +++ b/apps/openmw/mwlua/worldview.cpp @@ -8,6 +8,7 @@ #include "../mwclass/container.hpp" +#include "../mwworld/cells.hpp" #include "../mwworld/cellutils.hpp" #include "../mwworld/class.hpp" #include "../mwworld/timestamp.hpp" @@ -126,31 +127,30 @@ namespace MWLua // sections. MWWorld::CellStore* WorldView::findCell(const std::string& name, osg::Vec3f position) { - MWBase::World* world = MWBase::Environment::get().getWorld(); - bool exterior = name.empty() || world->getExterior(name); + MWWorld::Cells* cells = MWBase::Environment::get().getWorldModel(); + bool exterior = name.empty() || MWBase::Environment::get().getWorld()->getExterior(name); if (exterior) { const osg::Vec2i cellIndex = MWWorld::positionToCellIndex(position.x(), position.y()); - return world->getExterior(cellIndex.x(), cellIndex.y()); + return cells->getExterior(cellIndex.x(), cellIndex.y()); } else - return world->getInterior(name); + return cells->getInterior(name); } MWWorld::CellStore* WorldView::findNamedCell(const std::string& name) { - MWBase::World* world = MWBase::Environment::get().getWorld(); - const ESM::Cell* esmCell = world->getExterior(name); + MWWorld::Cells* cells = MWBase::Environment::get().getWorldModel(); + const ESM::Cell* esmCell = MWBase::Environment::get().getWorld()->getExterior(name); if (esmCell) - return world->getExterior(esmCell->getGridX(), esmCell->getGridY()); + return cells->getExterior(esmCell->getGridX(), esmCell->getGridY()); else - return world->getInterior(name); + return cells->getInterior(name); } MWWorld::CellStore* WorldView::findExteriorCell(int x, int y) { - MWBase::World* world = MWBase::Environment::get().getWorld(); - return world->getExterior(x, y); + return MWBase::Environment::get().getWorldModel()->getExterior(x, y); } } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index b89e32b72c..02f7902454 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -22,6 +22,7 @@ #include "../mwworld/esmstore.hpp" #include "../mwworld/inventorystore.hpp" #include "../mwworld/player.hpp" +#include "../mwworld/scene.hpp" #include "../mwbase/dialoguemanager.hpp" #include "../mwbase/environment.hpp" @@ -1570,7 +1571,8 @@ namespace MWMechanics } else { - const bool cellChanged = world->hasCellChanged(); + MWWorld::Scene* worldScene = MWBase::Environment::get().getWorldScene(); + const bool cellChanged = worldScene->hasCellChanged(); const MWWorld::Ptr actorPtr = actor.getPtr(); // make a copy of the map key to avoid it being // invalidated when the player teleports updateActor(actorPtr, duration); @@ -1582,7 +1584,7 @@ namespace MWMechanics // There needs to be a magic effect update in between. ctrl.updateContinuousVfx(); - if (!cellChanged && world->hasCellChanged()) + if (!cellChanged && worldScene->hasCellChanged()) { return; // for now abort update of the old cell when cell changes by teleportation magic effect // a better solution might be to apply cell changes at the end of the frame diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 6a21411315..4cf3f3ac6c 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -10,7 +10,7 @@ #include #include -#include "../mwphysics/collisiontype.hpp" +#include "../mwphysics/raycasting.hpp" #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" @@ -596,8 +596,8 @@ namespace MWMechanics osg::Vec3f fallbackDirection = actor.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0, -1, 0); osg::Vec3f destination = source + fallbackDirection * (halfExtents.y() + 16); - bool isObstacleDetected = MWBase::Environment::get().getWorld()->castRay( - source.x(), source.y(), source.z(), destination.x(), destination.y(), destination.z(), mask); + const auto* rayCasting = MWBase::Environment::get().getWorld()->getRayCasting(); + bool isObstacleDetected = rayCasting->castRay(source, destination, mask).mHit; if (isObstacleDetected) return; @@ -606,8 +606,7 @@ namespace MWMechanics // If we did not hit anything, there is a cliff behind actor. source = pos + osg::Vec3f(0, 0, 0.75f * halfExtents.z()) + fallbackDirection * (halfExtents.y() + 96); destination = source - osg::Vec3f(0, 0, 0.75f * halfExtents.z() + 96); - bool isCliffDetected = !MWBase::Environment::get().getWorld()->castRay( - source.x(), source.y(), source.z(), destination.x(), destination.y(), destination.z(), mask); + bool isCliffDetected = !rayCasting->castRay(source, destination, mask).mHit; if (isCliffDetected) return; diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index 68dfaff7cf..689a3b0a95 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -15,6 +15,8 @@ #include "../mwworld/class.hpp" #include "../mwworld/inventorystore.hpp" +#include "../mwphysics/raycasting.hpp" + #include "actorutil.hpp" #include "creaturestats.hpp" #include "movement.hpp" @@ -339,8 +341,12 @@ bool MWMechanics::AiPackage::shortcutPath(const osg::Vec3f& startPoint, const os if (!mShortcutProhibited || (mShortcutFailPos - startPoint).length() >= PATHFIND_SHORTCUT_RETRY_DIST) { // check if target is clearly visible - isPathClear = !MWBase::Environment::get().getWorld()->castRay( - startPoint.x(), startPoint.y(), startPoint.z(), endPoint.x(), endPoint.y(), endPoint.z()); + isPathClear + = !MWBase::Environment::get() + .getWorld() + ->getRayCasting() + ->castRay(startPoint, endPoint, MWPhysics::CollisionType_World | MWPhysics::CollisionType_Door) + .mHit; if (destInLOS != nullptr) *destInLOS = isPathClear; diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 1aeab99767..c9307abce9 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -18,7 +18,7 @@ #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" -#include "../mwphysics/collisiontype.hpp" +#include "../mwphysics/raycasting.hpp" #include "actorutil.hpp" #include "creaturestats.hpp" @@ -81,7 +81,11 @@ namespace MWMechanics + direction * std::max(halfExtents.x(), std::max(halfExtents.y(), halfExtents.z())); const int mask = MWPhysics::CollisionType_World | MWPhysics::CollisionType_HeightMap | MWPhysics::CollisionType_Door | MWPhysics::CollisionType_Actor; - return MWBase::Environment::get().getWorld()->castRay(position, visibleDestination, mask, actor); + return MWBase::Environment::get() + .getWorld() + ->getRayCasting() + ->castRay(position, visibleDestination, actor, {}, mask) + .mHit; } void stopMovement(const MWWorld::Ptr& actor) diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index 02dfd17a93..6e9ea28f93 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -14,7 +14,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" -#include "../mwphysics/collisiontype.hpp" +#include "../mwphysics/raycasting.hpp" #include "../mwworld/cellstore.hpp" #include "../mwworld/class.hpp" @@ -252,8 +252,12 @@ namespace MWMechanics // Add Z offset since path node can overlap with other objects. // Also ignore doors in raytesting. const int mask = MWPhysics::CollisionType_World; - bool isPathClear = !MWBase::Environment::get().getWorld()->castRay( - startPoint.x(), startPoint.y(), startPoint.z() + 16, temp.mX, temp.mY, temp.mZ + 16, mask); + bool isPathClear = !MWBase::Environment::get() + .getWorld() + ->getRayCasting() + ->castRay(osg::Vec3f(startPoint.x(), startPoint.y(), startPoint.z() + 16), + osg::Vec3f(temp.mX, temp.mY, temp.mZ + 16), mask) + .mHit; if (isPathClear) path.pop_front(); } diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index 4b67d9cb13..923ace45bb 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -222,6 +222,7 @@ namespace MWPhysics const MWWorld::ConstPtr& ignore = MWWorld::ConstPtr(), const std::vector& targets = std::vector(), int mask = CollisionType_Default, int group = 0xff) const override; + using RayCastingInterface::castRay; RayCastingResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius, int mask = CollisionType_Default, int group = 0xff) const override; diff --git a/apps/openmw/mwphysics/raycasting.hpp b/apps/openmw/mwphysics/raycasting.hpp index b46721358d..a8257ba31d 100644 --- a/apps/openmw/mwphysics/raycasting.hpp +++ b/apps/openmw/mwphysics/raycasting.hpp @@ -34,6 +34,11 @@ namespace MWPhysics const std::vector& targets = std::vector(), int mask = CollisionType_Default, int group = 0xff) const = 0; + RayCastingResult castRay(const osg::Vec3f& from, const osg::Vec3f& to, int mask) const + { + return castRay(from, to, MWWorld::ConstPtr(), std::vector(), mask); + } + virtual RayCastingResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius, int mask = CollisionType_Default, int group = 0xff) const = 0; diff --git a/apps/openmw/mwscript/cellextensions.cpp b/apps/openmw/mwscript/cellextensions.cpp index 6f5a4c97f0..b5a540fd81 100644 --- a/apps/openmw/mwscript/cellextensions.cpp +++ b/apps/openmw/mwscript/cellextensions.cpp @@ -16,6 +16,7 @@ #include "../mwbase/world.hpp" #include "../mwworld/actionteleport.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/scene.hpp" #include "../mwmechanics/actorutil.hpp" @@ -30,7 +31,7 @@ namespace MWScript public: void execute(Interpreter::Runtime& runtime) override { - runtime.push(MWBase::Environment::get().getWorld()->hasCellChanged() ? 1 : 0); + runtime.push(MWBase::Environment::get().getWorldScene()->hasCellChanged() ? 1 : 0); } }; @@ -50,7 +51,7 @@ namespace MWScript if (wasConsole) MWBase::Environment::get().getWindowManager()->toggleConsole(); - MWBase::Environment::get().getWorld()->testExteriorCells(); + MWBase::Environment::get().getWorldScene()->testExteriorCells(); if (wasConsole) MWBase::Environment::get().getWindowManager()->toggleConsole(); @@ -73,7 +74,7 @@ namespace MWScript if (wasConsole) MWBase::Environment::get().getWindowManager()->toggleConsole(); - MWBase::Environment::get().getWorld()->testInteriorCells(); + MWBase::Environment::get().getWorldScene()->testInteriorCells(); if (wasConsole) MWBase::Environment::get().getWindowManager()->toggleConsole(); diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index b2d95c8cea..518de3a3a2 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -13,11 +13,13 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwworld/cells.hpp" #include "../mwworld/cellstore.hpp" #include "../mwworld/cellutils.hpp" #include "../mwworld/class.hpp" #include "../mwworld/manualref.hpp" #include "../mwworld/player.hpp" +#include "../mwworld/scene.hpp" #include "../mwmechanics/actorutil.hpp" @@ -388,6 +390,7 @@ namespace MWScript bool isPlayer = ptr == MWMechanics::getPlayer(); auto world = MWBase::Environment::get().getWorld(); + auto worldModel = MWBase::Environment::get().getWorldModel(); if (isPlayer) { world->getPlayer().setTeleported(true); @@ -396,7 +399,7 @@ namespace MWScript MWWorld::CellStore* store = nullptr; try { - store = world->getInterior(cellID); + store = worldModel->getInterior(cellID); } catch (std::exception&) { @@ -415,7 +418,7 @@ namespace MWScript return; } const osg::Vec2i cellIndex = MWWorld::positionToCellIndex(x, y); - store = world->getExterior(cellIndex.x(), cellIndex.y()); + store = worldModel->getExterior(cellIndex.x(), cellIndex.y()); } if (store) { @@ -432,7 +435,8 @@ namespace MWScript rot.z() = osg::DegreesToRadians(zRot); world->rotateObject(ptr, rot); - ptr.getClass().adjustPosition(ptr, isPlayer || !world->isCellActive(ptr.getCell())); + bool cellActive = MWBase::Environment::get().getWorldScene()->isCellActive(*ptr.getCell()); + ptr.getClass().adjustPosition(ptr, isPlayer || !cellActive); } } }; @@ -470,7 +474,8 @@ namespace MWScript MWWorld::Ptr base = ptr; if (isPlayer) { - MWWorld::CellStore* cell = world->getExterior(cellIndex.x(), cellIndex.y()); + MWWorld::CellStore* cell + = MWBase::Environment::get().getWorldModel()->getExterior(cellIndex.x(), cellIndex.y()); ptr = world->moveObject(ptr, cell, osg::Vec3(x, y, z)); } else @@ -487,7 +492,8 @@ namespace MWScript zRot = zRot / 60.0f; rot.z() = osg::DegreesToRadians(zRot); world->rotateObject(ptr, rot); - ptr.getClass().adjustPosition(ptr, isPlayer || !world->isCellActive(ptr.getCell())); + bool cellActive = MWBase::Environment::get().getWorldScene()->isCellActive(*ptr.getCell()); + ptr.getClass().adjustPosition(ptr, isPlayer || !cellActive); } }; @@ -513,13 +519,13 @@ namespace MWScript MWWorld::CellStore* store = nullptr; try { - store = MWBase::Environment::get().getWorld()->getInterior(cellID); + store = MWBase::Environment::get().getWorldModel()->getInterior(cellID); } catch (std::exception&) { const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getExterior(cellID); const osg::Vec2i cellIndex = MWWorld::positionToCellIndex(x, y); - store = MWBase::Environment::get().getWorld()->getExterior(cellIndex.x(), cellIndex.y()); + store = MWBase::Environment::get().getWorldModel()->getExterior(cellIndex.x(), cellIndex.y()); if (!cell) { runtime.getContext().report("unknown cell (" + std::string(cellID) + ")"); @@ -569,7 +575,7 @@ namespace MWScript if (player.getCell()->isExterior()) { const osg::Vec2i cellIndex = MWWorld::positionToCellIndex(x, y); - store = MWBase::Environment::get().getWorld()->getExterior(cellIndex.x(), cellIndex.y()); + store = MWBase::Environment::get().getWorldModel()->getExterior(cellIndex.x(), cellIndex.y()); } else store = player.getCell(); diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index 68c29252f4..8d13526fb6 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -30,9 +30,11 @@ #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" +#include "../mwworld/cells.hpp" #include "../mwworld/cellstore.hpp" #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/scene.hpp" #include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/npcstats.hpp" @@ -554,7 +556,7 @@ 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().getWorld()->getExterior(0, 0); + MWWorld::CellStore* cell = MWBase::Environment::get().getWorldModel()->getExterior(0, 0); float x, y; MWBase::Environment::get().getWorld()->indexToPosition(0, 0, x, y, false); ESM::Position pos; @@ -575,7 +577,7 @@ void MWState::StateManager::loadGame(const Character* character, const std::file // Since we passed "changeEvent=false" to changeCell, we shouldn't have triggered the cell change flag. // But make sure the flag is cleared anyway in case it was set from an earlier game. - MWBase::Environment::get().getWorld()->markCellAsUnchanged(); + MWBase::Environment::get().getWorldScene()->markCellAsUnchanged(); MWBase::Environment::get().getLuaManager()->gameLoaded(); } diff --git a/apps/openmw/mwworld/actionteleport.cpp b/apps/openmw/mwworld/actionteleport.cpp index 8754e2ba0e..19c6ec65b6 100644 --- a/apps/openmw/mwworld/actionteleport.cpp +++ b/apps/openmw/mwworld/actionteleport.cpp @@ -8,6 +8,7 @@ #include "../mwmechanics/creaturestats.hpp" +#include "../mwworld/cells.hpp" #include "../mwworld/cellstore.hpp" #include "../mwworld/cellutils.hpp" #include "../mwworld/class.hpp" @@ -42,6 +43,7 @@ namespace MWWorld void ActionTeleport::teleport(const Ptr& actor) { MWBase::World* world = MWBase::Environment::get().getWorld(); + MWWorld::Cells* worldModel = MWBase::Environment::get().getWorldModel(); actor.getClass().getCreatureStats(actor).land(actor == world->getPlayerPtr()); if (actor == world->getPlayerPtr()) { @@ -58,10 +60,10 @@ namespace MWWorld else if (mCellName.empty()) { const osg::Vec2i index = positionToCellIndex(mPosition.pos[0], mPosition.pos[1]); - world->moveObject(actor, world->getExterior(index.x(), index.y()), mPosition.asVec3(), true, true); + world->moveObject(actor, worldModel->getExterior(index.x(), index.y()), mPosition.asVec3(), true, true); } else - world->moveObject(actor, world->getInterior(mCellName), mPosition.asVec3(), true, true); + world->moveObject(actor, worldModel->getInterior(mCellName), mPosition.asVec3(), true, true); } } diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 200f97e543..819ddd9538 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -12,6 +12,7 @@ #include #include +#include "../mwworld/cells.hpp" #include "../mwworld/esmstore.hpp" #include "../mwworld/inventorystore.hpp" #include "../mwworld/magiceffects.hpp" @@ -430,7 +431,7 @@ namespace MWWorld try { - mCellStore = world.getCell(player.mCellId); + mCellStore = MWBase::Environment::get().getWorldModel()->getCell(player.mCellId); } catch (...) { @@ -467,7 +468,7 @@ namespace MWWorld if (player.mHasMark) { mMarkedPosition = player.mMarkedPosition; - mMarkedCell = world.getCell(player.mMarkedCell); + mMarkedCell = MWBase::Environment::get().getWorldModel()->getCell(player.mMarkedCell); } else { diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 549f77b07a..8d5672f7ce 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -543,7 +543,8 @@ namespace MWWorld } mNavigator.setWorldspace( - mWorld.getExterior(playerCellX, playerCellY)->getCell()->mCellId.mWorldspace, navigatorUpdateGuard.get()); + mWorld.getWorldModel().getExterior(playerCellX, playerCellY)->getCell()->mCellId.mWorldspace, + navigatorUpdateGuard.get()); mNavigator.updateBounds(pos, navigatorUpdateGuard.get()); mCurrentGridCenter = osg::Vec2i(playerCellX, playerCellY); @@ -566,7 +567,7 @@ namespace MWWorld { if (!isCellInCollection(x, y, collection)) { - refsToLoad += mWorld.getExterior(x, y)->count(); + refsToLoad += mWorld.getWorldModel().getExterior(x, y)->count(); cellsPositionsToLoad.emplace_back(x, y); } } @@ -601,7 +602,7 @@ namespace MWWorld { if (!isCellInCollection(x, y, mActiveCells)) { - CellStore* cell = mWorld.getExterior(x, y); + CellStore* cell = mWorld.getWorldModel().getExterior(x, y); loadCell(cell, loadingListener, changeEvent, pos, navigatorUpdateGuard.get()); } } @@ -610,7 +611,7 @@ namespace MWWorld navigatorUpdateGuard.reset(); - CellStore* current = mWorld.getExterior(playerCellX, playerCellY); + CellStore* current = mWorld.getWorldModel().getExterior(playerCellX, playerCellY); MWBase::Environment::get().getWindowManager()->changeCell(current); if (changeEvent) @@ -663,7 +664,7 @@ namespace MWWorld loadingListener->setLabel( "Testing exterior cells (" + std::to_string(i) + "/" + std::to_string(cells.getExtSize()) + ")..."); - CellStore* cell = mWorld.getExterior(it->mData.mX, it->mData.mY); + CellStore* cell = mWorld.getWorldModel().getExterior(it->mData.mX, it->mData.mY); mNavigator.setWorldspace(cell->getCell()->mCellId.mWorldspace, navigatorUpdateGuard.get()); const osg::Vec3f position = osg::Vec3f(it->mData.mX + 0.5f, it->mData.mY + 0.5f, 0) * Constants::CellSizeInUnits; @@ -720,7 +721,7 @@ namespace MWWorld loadingListener->setLabel( "Testing interior cells (" + std::to_string(i) + "/" + std::to_string(cells.getIntSize()) + ")..."); - CellStore* cell = mWorld.getInterior(it->mName); + CellStore* cell = mWorld.getWorldModel().getInterior(it->mName); mNavigator.setWorldspace(cell->getCell()->mCellId.mWorldspace, navigatorUpdateGuard.get()); ESM::Position position; mWorld.findInteriorPosition(it->mName, position); @@ -842,7 +843,7 @@ namespace MWWorld void Scene::changeToInteriorCell( const std::string& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent) { - CellStore* cell = mWorld.getInterior(cellName); + CellStore* cell = mWorld.getWorldModel().getInterior(cellName); bool useFading = (mCurrentCell != nullptr); if (useFading) MWBase::Environment::get().getWindowManager()->fadeScreenOut(0.5); @@ -917,7 +918,7 @@ namespace MWWorld changeCellGrid(position.asVec3(), cellIndex.x(), cellIndex.y(), changeEvent); - CellStore* current = mWorld.getExterior(cellIndex.x(), cellIndex.y()); + CellStore* current = mWorld.getWorldModel().getExterior(cellIndex.x(), cellIndex.y()); changePlayerCell(current, position, adjustPlayerPos); if (changeEvent) @@ -1116,12 +1117,12 @@ namespace MWWorld try { if (!door.getCellRef().getDestCell().empty()) - preloadCell(mWorld.getInterior(door.getCellRef().getDestCell())); + preloadCell(mWorld.getWorldModel().getInterior(door.getCellRef().getDestCell())); else { osg::Vec3f pos = door.getCellRef().getDoorDest().asVec3(); const osg::Vec2i cellIndex = positionToCellIndex(pos.x(), pos.y()); - preloadCell(mWorld.getExterior(cellIndex.x(), cellIndex.y()), true); + preloadCell(mWorld.getWorldModel().getExterior(cellIndex.x(), cellIndex.y()), true); exteriorPositions.emplace_back(pos, gridCenterToBounds(getNewGridCenter(pos))); } } @@ -1167,7 +1168,7 @@ namespace MWWorld + mPreloadDistance; if (dist < loadDist) - preloadCell(mWorld.getExterior(cellX + dx, cellY + dy)); + preloadCell(mWorld.getWorldModel().getExterior(cellX + dx, cellY + dy)); } } } @@ -1183,7 +1184,8 @@ namespace MWWorld { for (int dy = -mHalfGridSize; dy <= mHalfGridSize; ++dy) { - mPreloader->preload(mWorld.getExterior(x + dx, y + dy), mRendering.getReferenceTime()); + mPreloader->preload( + mWorld.getWorldModel().getExterior(x + dx, y + dy), mRendering.getReferenceTime()); if (++numpreloaded >= mPreloader->getMaxCacheSize()) break; } @@ -1263,12 +1265,12 @@ namespace MWWorld for (ESM::Transport::Dest& dest : listVisitor.mList) { if (!dest.mCellName.empty()) - preloadCell(mWorld.getInterior(dest.mCellName)); + preloadCell(mWorld.getWorldModel().getInterior(dest.mCellName)); else { osg::Vec3f pos = dest.mPos.asVec3(); const osg::Vec2i cellIndex = positionToCellIndex(pos.x(), pos.y()); - preloadCell(mWorld.getExterior(cellIndex.x(), cellIndex.y()), true); + preloadCell(mWorld.getWorldModel().getExterior(cellIndex.x(), cellIndex.y()), true); exteriorPositions.emplace_back(pos, gridCenterToBounds(getNewGridCenter(pos))); } } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 1a547e9387..e8959d70ff 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -592,39 +592,6 @@ namespace MWWorld return nullptr; } - CellStore* World::getExterior(int x, int y) - { - return mCells.getExterior(x, y); - } - - CellStore* World::getInterior(std::string_view name) - { - return mCells.getInterior(name); - } - - CellStore* World::getCell(const ESM::CellId& id) - { - if (id.mPaged) - return getExterior(id.mIndex.mX, id.mIndex.mY); - else - return getInterior(id.mWorldspace); - } - - bool World::isCellActive(CellStore* cell) const - { - return mWorldScene->getActiveCells().count(cell) > 0; - } - - void World::testExteriorCells() - { - mWorldScene->testExteriorCells(); - } - - void World::testInteriorCells() - { - mWorldScene->testInteriorCells(); - } - void World::useDeathCamera() { mRendering->getCamera()->setMode(MWRender::Camera::Mode::ThirdPerson); @@ -650,11 +617,6 @@ namespace MWWorld return mLocalScripts; } - bool World::hasCellChanged() const - { - return mWorldScene->hasCellChanged(); - } - void World::setGlobalInt(std::string_view name, int value) { bool dateUpdated = mCurrentDate->updateGlobalInt(name, value); @@ -1045,11 +1007,6 @@ namespace MWWorld mCurrentDate->setup(mGlobalVariables); } - void World::markCellAsUnchanged() - { - return mWorldScene->markCellAsUnchanged(); - } - float World::getMaxActivationDistance() const { if (mActivationDistanceOverride >= 0) @@ -1305,7 +1262,7 @@ namespace MWWorld const osg::Vec2i index = positionToCellIndex(position.x(), position.y()); CellStore* cell = ptr.getCell(); - CellStore* newCell = getExterior(index.x(), index.y()); + CellStore* newCell = mCells.getExterior(index.x(), index.y()); bool isCellActive = getPlayerPtr().isInCell() && getPlayerPtr().getCell()->isExterior() && mWorldScene->isCellActive(*newCell); @@ -1455,7 +1412,7 @@ namespace MWWorld targetPos = pos + (orientation * osg::Vec3f(1, 0, 0)) * distance; // destination is free - if (!castRay(pos.x(), pos.y(), pos.z(), targetPos.x(), targetPos.y(), targetPos.z())) + if (!mPhysics->castRay(pos, targetPos, MWPhysics::CollisionType_World | MWPhysics::CollisionType_Door).mHit) break; } @@ -1522,7 +1479,10 @@ namespace MWWorld // check if spawn point is safe, fall back to another direction if not spawnPoint.z() += 30; // move up a little to account for slopes, will snap down later - if (!castRay(spawnPoint.x(), spawnPoint.y(), spawnPoint.z(), pos.x(), pos.y(), pos.z() + 20)) + if (!mPhysics + ->castRay(spawnPoint, osg::Vec3f(pos.x(), pos.y(), pos.z() + 20), + MWPhysics::CollisionType_World | MWPhysics::CollisionType_Door) + .mHit) { // safe break; @@ -1611,27 +1571,6 @@ namespace MWWorld return mPhysics.get(); } - bool World::castRay(float x1, float y1, float z1, float x2, float y2, float z2) - { - int mask = MWPhysics::CollisionType_World | MWPhysics::CollisionType_Door; - bool result = castRay(x1, y1, z1, x2, y2, z2, mask); - return result; - } - - bool World::castRay(float x1, float y1, float z1, float x2, float y2, float z2, int mask) - { - osg::Vec3f a(x1, y1, z1); - osg::Vec3f b(x2, y2, z2); - - MWPhysics::RayCastingResult result = mPhysics->castRay(a, b, MWWorld::Ptr(), std::vector(), mask); - return result.mHit; - } - - bool World::castRay(const osg::Vec3f& from, const osg::Vec3f& to, int mask, const MWWorld::ConstPtr& ignore) - { - return mPhysics->castRay(from, to, ignore, std::vector(), mask).mHit; - } - bool World::rotateDoor(const Ptr door, MWWorld::DoorState state, float duration) { const ESM::Position& objPos = door.getRefData().getPosition(); @@ -2850,7 +2789,7 @@ namespace MWWorld pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; pos.pos[0] = pos.pos[1] = pos.pos[2] = 0; - MWWorld::CellStore* cellStore = getInterior(name); + MWWorld::CellStore* cellStore = mCells.getInterior(name); if (!cellStore) return false; @@ -2881,12 +2820,12 @@ namespace MWWorld { ESM::Position doorDest = door->getDoorDest(); const osg::Vec2i index = positionToCellIndex(doorDest.pos[0], doorDest.pos[1]); - source = getExterior(index.x(), index.y()); + source = mCells.getExterior(index.x(), index.y()); } // door to interior else { - source = getInterior(door->getDestCell()); + source = mCells.getInterior(door->getDestCell()); } if (source) { @@ -2933,7 +2872,7 @@ namespace MWWorld if (xResult.ec == std::errc::result_out_of_range || yResult.ec == std::errc::result_out_of_range) throw std::runtime_error("Cell coordinates out of range."); else if (xResult.ec == std::errc{} && yResult.ec == std::errc{}) - ext = getExterior(x, y)->getCell(); + ext = mCells.getExterior(x, y)->getCell(); // ignore std::errc::invalid_argument, as this means that name probably refers to a interior cell // instead of comma separated coordinates } @@ -3352,7 +3291,7 @@ namespace MWWorld nextCells.clear(); for (const std::string& currentCell : currentCells) { - MWWorld::CellStore* next = getInterior(currentCell); + MWWorld::CellStore* next = mCells.getInterior(currentCell); if (!next) continue; @@ -3406,7 +3345,7 @@ namespace MWWorld nextCells.clear(); for (const std::string& cell : currentCells) { - MWWorld::CellStore* next = getInterior(cell); + MWWorld::CellStore* next = mCells.getInterior(cell); checkedCells.insert(cell); if (!next) continue; @@ -3704,7 +3643,7 @@ namespace MWWorld Log(Debug::Warning) << "Failed to confiscate items: prison marker not linked to prison interior"; return; } - MWWorld::CellStore* prison = getInterior(prisonName); + MWWorld::CellStore* prison = mCells.getInterior(prisonName); if (!prison) { Log(Debug::Warning) << "Failed to confiscate items: failed to load cell " << prisonName; diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 571b0963eb..6ebf90ea46 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -188,6 +188,9 @@ namespace MWWorld MWWorld::ConstPtr getClosestMarkerFromExteriorPosition(const osg::Vec3f& worldPos, std::string_view id); public: + Cells& getWorldModel() { return mCells; } + Scene& getWorldScene() { return *mWorldScene; } + // FIXME void addContainerScripts(const Ptr& reference, CellStore* cell) override; void removeContainerScripts(const Ptr& reference) override; @@ -215,17 +218,6 @@ namespace MWWorld void readRecord(ESM::ESMReader& reader, uint32_t type, const std::map& contentFileMap) override; - CellStore* getExterior(int x, int y) override; - - CellStore* getInterior(std::string_view name) override; - - CellStore* getCell(const ESM::CellId& id) override; - - bool isCellActive(CellStore* cell) const override; - - void testExteriorCells() override; - void testInteriorCells() override; - // switch to POV before showing player's death animation void useDeathCamera() override; @@ -249,9 +241,6 @@ namespace MWWorld LocalScripts& getLocalScripts() override; - bool hasCellChanged() const override; - ///< Has the set of active cells changed, since the last frame? - bool isCellExterior() const override; bool isCellQuasiExterior() const override; @@ -371,8 +360,6 @@ namespace MWWorld const ESM::Cell* getExterior(std::string_view cellName) const override; ///< Return a cell matching the given name or a 0-pointer, if there is no such cell. - void markCellAsUnchanged() override; - MWWorld::Ptr getFacedObject() override; ///< Return pointer to the object the player is looking at, if it is within activation range @@ -433,13 +420,6 @@ namespace MWWorld const MWPhysics::RayCastingInterface* getRayCasting() const override; - bool castRay(float x1, float y1, float z1, float x2, float y2, float z2, int mask) override; - ///< cast a Ray and return true if there is an object in the ray path. - - bool castRay(float x1, float y1, float z1, float x2, float y2, float z2) override; - - bool castRay(const osg::Vec3f& from, const osg::Vec3f& to, int mask, const MWWorld::ConstPtr& ignore) override; - bool castRenderingRay(MWPhysics::RayCastingResult& res, const osg::Vec3f& from, const osg::Vec3f& to, bool ignorePlayer, bool ignoreActors) override;