diff --git a/apps/openmw/mwclass/activator.cpp b/apps/openmw/mwclass/activator.cpp index e4ba7af4f0..6285bdbf7e 100644 --- a/apps/openmw/mwclass/activator.cpp +++ b/apps/openmw/mwclass/activator.cpp @@ -38,15 +38,15 @@ namespace MWClass } } - void Activator::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const + void Activator::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const { - insertObjectPhysics(ptr, model, rotation, physics, skipAnimated); + insertObjectPhysics(ptr, model, rotation, physics); } - void Activator::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const + void Activator::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const { if(!model.empty()) - physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World, skipAnimated); + physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World); } std::string Activator::getModel(const MWWorld::ConstPtr &ptr) const diff --git a/apps/openmw/mwclass/activator.hpp b/apps/openmw/mwclass/activator.hpp index 32bf1564c9..48a679e0b7 100644 --- a/apps/openmw/mwclass/activator.hpp +++ b/apps/openmw/mwclass/activator.hpp @@ -17,9 +17,9 @@ namespace MWClass void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; - void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const override; + void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. diff --git a/apps/openmw/mwclass/actor.cpp b/apps/openmw/mwclass/actor.cpp index b142fd2643..ad43bd6e5f 100644 --- a/apps/openmw/mwclass/actor.cpp +++ b/apps/openmw/mwclass/actor.cpp @@ -22,7 +22,7 @@ namespace MWClass MWBase::Environment::get().getWorld()->adjustPosition(ptr, force); } - void Actor::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const + void Actor::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const { if (!model.empty()) { diff --git a/apps/openmw/mwclass/actor.hpp b/apps/openmw/mwclass/actor.hpp index 6a5d4c5150..886ffe4771 100644 --- a/apps/openmw/mwclass/actor.hpp +++ b/apps/openmw/mwclass/actor.hpp @@ -24,7 +24,7 @@ namespace MWClass ///< Adjust position to stand on ground. Must be called post model load /// @param force do this even if the ptr is flying - void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; bool useAnim() const override; diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index 051fbafeb5..06980f55da 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -106,15 +106,15 @@ namespace MWClass } } - void Container::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const + void Container::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const { - insertObjectPhysics(ptr, model, rotation, physics, skipAnimated); + insertObjectPhysics(ptr, model, rotation, physics); } - void Container::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const + void Container::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const { if(!model.empty()) - physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World, skipAnimated); + physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World); } std::string Container::getModel(const MWWorld::ConstPtr &ptr) const diff --git a/apps/openmw/mwclass/container.hpp b/apps/openmw/mwclass/container.hpp index 9407dab243..0b290a73e1 100644 --- a/apps/openmw/mwclass/container.hpp +++ b/apps/openmw/mwclass/container.hpp @@ -42,8 +42,8 @@ namespace MWClass void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override; - void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; + void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 70c4a27582..b5fe705ca6 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -55,9 +55,9 @@ namespace MWClass } } - void Door::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const + void Door::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const { - insertObjectPhysics(ptr, model, rotation, physics, skipAnimated); + insertObjectPhysics(ptr, model, rotation, physics); // Resume the door's opening/closing animation if it wasn't finished if (ptr.getRefData().getCustomData()) @@ -70,10 +70,10 @@ namespace MWClass } } - void Door::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const + void Door::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const { if(!model.empty()) - physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_Door, skipAnimated); + physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_Door); } bool Door::isDoor() const diff --git a/apps/openmw/mwclass/door.hpp b/apps/openmw/mwclass/door.hpp index 1fd59f8f52..f9288a88ce 100644 --- a/apps/openmw/mwclass/door.hpp +++ b/apps/openmw/mwclass/door.hpp @@ -18,8 +18,8 @@ namespace MWClass void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override; - void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; + void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; bool isDoor() const override; diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 0281861980..69cc1a09bf 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -33,13 +33,13 @@ namespace MWClass renderingInterface.getObjects().insertModel(ptr, model, true, !(ref->mBase->mData.mFlags & ESM::Light::OffDefault)); } - void Light::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const + void Light::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const { MWWorld::LiveCellRef *ref = ptr.get(); assert (ref->mBase != nullptr); - insertObjectPhysics(ptr, model, rotation, physics, skipAnimated); + insertObjectPhysics(ptr, model, rotation, physics); if (!ref->mBase->mSound.empty() && !(ref->mBase->mData.mFlags & ESM::Light::OffDefault)) MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->mBase->mSound, 1.0, 1.0, @@ -47,11 +47,11 @@ namespace MWClass MWSound::PlayMode::Loop); } - void Light::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const + void Light::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const { // TODO: add option somewhere to enable collision for placeable objects if (!model.empty() && (ptr.get()->mBase->mData.mFlags & ESM::Light::Carry) == 0) - physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World, skipAnimated); + physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World); } bool Light::useAnim() const diff --git a/apps/openmw/mwclass/light.hpp b/apps/openmw/mwclass/light.hpp index 206abede43..e8aa4e5878 100644 --- a/apps/openmw/mwclass/light.hpp +++ b/apps/openmw/mwclass/light.hpp @@ -14,8 +14,8 @@ namespace MWClass void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override; - void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; + void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; bool useAnim() const override; diff --git a/apps/openmw/mwclass/static.cpp b/apps/openmw/mwclass/static.cpp index 5cbe219580..0805ca3dd1 100644 --- a/apps/openmw/mwclass/static.cpp +++ b/apps/openmw/mwclass/static.cpp @@ -23,15 +23,15 @@ namespace MWClass } } - void Static::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const + void Static::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const { - insertObjectPhysics(ptr, model, rotation, physics, skipAnimated); + insertObjectPhysics(ptr, model, rotation, physics); } - void Static::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const + void Static::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const { if(!model.empty()) - physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World, skipAnimated); + physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World); } std::string Static::getModel(const MWWorld::ConstPtr &ptr) const diff --git a/apps/openmw/mwclass/static.hpp b/apps/openmw/mwclass/static.hpp index 7c326987a8..c747eebf2f 100644 --- a/apps/openmw/mwclass/static.hpp +++ b/apps/openmw/mwclass/static.hpp @@ -14,8 +14,8 @@ namespace MWClass void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override; - void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; + void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. diff --git a/apps/openmw/mwmechanics/actor.cpp b/apps/openmw/mwmechanics/actor.cpp index a5c55633ac..5801ea751d 100644 --- a/apps/openmw/mwmechanics/actor.cpp +++ b/apps/openmw/mwmechanics/actor.cpp @@ -5,6 +5,7 @@ namespace MWMechanics { Actor::Actor(const MWWorld::Ptr &ptr, MWRender::Animation *animation) + : mPositionAdjusted(false) { mCharacterController.reset(new CharacterController(ptr, animation)); } @@ -58,4 +59,14 @@ namespace MWMechanics { mIsTurningToPlayer = turning; } + + void Actor::setPositionAdjusted(bool adjusted) + { + mPositionAdjusted = adjusted; + } + + bool Actor::getPositionAdjusted() const + { + return mPositionAdjusted; + } } diff --git a/apps/openmw/mwmechanics/actor.hpp b/apps/openmw/mwmechanics/actor.hpp index be4f425378..c25fc1cb73 100644 --- a/apps/openmw/mwmechanics/actor.hpp +++ b/apps/openmw/mwmechanics/actor.hpp @@ -48,6 +48,9 @@ namespace MWMechanics return mEngageCombat.update(duration); } + void setPositionAdjusted(bool adjusted); + bool getPositionAdjusted() const; + private: std::unique_ptr mCharacterController; int mGreetingTimer{0}; @@ -55,6 +58,7 @@ namespace MWMechanics GreetingState mGreetingState{Greet_None}; bool mIsTurningToPlayer{false}; Misc::DeviatingPeriodicTimer mEngageCombat{1.0f, 0.25f, Misc::Rng::deviate(0, 0.25f)}; + bool mPositionAdjusted; }; } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 542f185854..1cd66291f0 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -2157,7 +2157,14 @@ namespace MWMechanics continue; } else if (!isPlayer) + { iter->first.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Actor); + if (!iter->second->getPositionAdjusted()) + { + iter->first.getClass().adjustPosition(iter->first, false); + iter->second->setPositionAdjusted(true); + } + } const bool isDead = iter->first.getClass().getCreatureStats(iter->first).isDead(); if (!isDead && (!godmode || !isPlayer) && iter->first.getClass().getCreatureStats(iter->first).isParalyzed()) diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 903e383370..23ece987ef 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -492,7 +492,7 @@ namespace MWPhysics return heightField->second.get(); } - void PhysicsSystem::addObject (const MWWorld::Ptr& ptr, const std::string& mesh, osg::Quat rotation, int collisionType, bool skipAnimated) + void PhysicsSystem::addObject (const MWWorld::Ptr& ptr, const std::string& mesh, osg::Quat rotation, int collisionType) { if (ptr.mRef->mData.mPhysicsPostponed) return; @@ -500,9 +500,6 @@ namespace MWPhysics if (!shapeInstance || !shapeInstance->getCollisionShape()) return; - if (skipAnimated && shapeInstance->isAnimated()) - return; - assert(!getObject(ptr)); auto obj = std::make_shared(ptr, shapeInstance, rotation, collisionType, mTaskScheduler.get()); diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index 52515b563f..bc358cb3c4 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -128,7 +128,7 @@ namespace MWPhysics void setWaterHeight(float height); void disableWater(); - void addObject (const MWWorld::Ptr& ptr, const std::string& mesh, osg::Quat rotation, int collisionType = CollisionType_World, bool skipAnimated = false); + void addObject (const MWWorld::Ptr& ptr, const std::string& mesh, osg::Quat rotation, int collisionType = CollisionType_World); void addActor (const MWWorld::Ptr& ptr, const std::string& mesh); int addProjectile(const MWWorld::Ptr& caster, const osg::Vec3f& position, const std::string& mesh, bool computeRadius); diff --git a/apps/openmw/mwworld/cellvisitors.hpp b/apps/openmw/mwworld/cellvisitors.hpp index 81e1248e6d..77f33fa84b 100644 --- a/apps/openmw/mwworld/cellvisitors.hpp +++ b/apps/openmw/mwworld/cellvisitors.hpp @@ -25,16 +25,6 @@ namespace MWWorld } }; - struct ListObjectsVisitor - { - std::vector mObjects; - - bool operator() (const MWWorld::Ptr& ptr) - { - mObjects.push_back (ptr); - return true; - } - }; } #endif diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 55e39de55e..da4dd9d99e 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -30,12 +30,12 @@ namespace MWWorld } - void Class::insertObject(const Ptr& ptr, const std::string& mesh, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const + void Class::insertObject(const Ptr& ptr, const std::string& mesh, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const { } - void Class::insertObjectPhysics(const Ptr& ptr, const std::string& mesh, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const + void Class::insertObjectPhysics(const Ptr& ptr, const std::string& mesh, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const {} bool Class::apply (const MWWorld::Ptr& ptr, const std::string& id, const MWWorld::Ptr& actor) const diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 4779a3065b..8e451ea580 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -78,9 +78,9 @@ namespace MWWorld } virtual void insertObjectRendering (const Ptr& ptr, const std::string& mesh, MWRender::RenderingInterface& renderingInterface) const; - virtual void insertObject(const Ptr& ptr, const std::string& mesh, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const; + virtual void insertObject(const Ptr& ptr, const std::string& mesh, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const; ///< Add reference into a cell for rendering (default implementation: don't render anything). - virtual void insertObjectPhysics(const Ptr& ptr, const std::string& mesh, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const; + virtual void insertObjectPhysics(const Ptr& ptr, const std::string& mesh, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const; virtual std::string getName (const ConstPtr& ptr) const = 0; ///< \return name or ID; can return an empty string. diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 559ab4aef4..765464c8de 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -104,7 +104,7 @@ namespace } void addObject(const MWWorld::Ptr& ptr, MWPhysics::PhysicsSystem& physics, - MWRender::RenderingManager& rendering, std::set& pagedRefs, bool onlyPhysics) + MWRender::RenderingManager& rendering, std::set& pagedRefs) { if (ptr.getRefData().getBaseNode() || physics.getActor(ptr)) { @@ -114,12 +114,6 @@ namespace std::string model = getModel(ptr, rendering.getResourceSystem()->getVFS()); const auto rotation = makeNodeRotation(ptr, RotationOrder::direct); - if (onlyPhysics && !physics.getObject(ptr) && !ptr.getClass().isActor()) - { - // When we preload physics object we need to skip animated objects. They are dependant on the scene graph which doesn't yet exist. - ptr.getClass().insertObject (ptr, model, rotation, physics, true); - return; - } const ESM::RefNum& refnum = ptr.getCellRef().getRefNum(); if (!refnum.hasContentFile() || pagedRefs.find(refnum) == pagedRefs.end()) @@ -137,8 +131,7 @@ namespace // Restore effect particles MWBase::Environment::get().getWorld()->applyLoopingParticles(ptr); - if (!physics.getObject(ptr)) - ptr.getClass().insertObject (ptr, model, rotation, physics); + ptr.getClass().insertObject (ptr, model, rotation, physics); MWBase::Environment::get().getLuaManager()->objectAddedToScene(ptr); } @@ -201,11 +194,10 @@ namespace { MWWorld::CellStore& mCell; Loading::Listener* mLoadingListener; - bool mOnlyObjects; std::vector mToInsert; - InsertVisitor (MWWorld::CellStore& cell, Loading::Listener* loadingListener, bool onlyObjects); + InsertVisitor (MWWorld::CellStore& cell, Loading::Listener* loadingListener); bool operator() (const MWWorld::Ptr& ptr); @@ -213,8 +205,8 @@ namespace void insert(AddObject&& addObject); }; - InsertVisitor::InsertVisitor (MWWorld::CellStore& cell, Loading::Listener* loadingListener, bool onlyObjects) - : mCell(cell), mLoadingListener(loadingListener), mOnlyObjects(onlyObjects) + InsertVisitor::InsertVisitor (MWWorld::CellStore& cell, Loading::Listener* loadingListener) + : mCell(cell), mLoadingListener(loadingListener) {} bool InsertVisitor::operator() (const MWWorld::Ptr& ptr) @@ -230,7 +222,7 @@ namespace { for (MWWorld::Ptr& ptr : mToInsert) { - if (!ptr.getRefData().isDeleted() && ptr.getRefData().isEnabled() && (!mOnlyObjects || !ptr.getClass().isActor())) + if (!ptr.getRefData().isDeleted() && ptr.getRefData().isEnabled()) { try { @@ -248,16 +240,6 @@ namespace } } - struct PositionVisitor - { - bool operator() (const MWWorld::Ptr& ptr) - { - if (!ptr.getRefData().isDeleted() && ptr.getRefData().isEnabled()) - ptr.getClass().adjustPosition (ptr, false); - return true; - } - }; - int getCellPositionDistanceToOrigin(const std::pair& cellPosition) { return std::abs(cellPosition.first) + std::abs(cellPosition.second); @@ -324,39 +306,12 @@ namespace MWWorld mRendering.update (duration, paused); } - void Scene::unloadInactiveCell (CellStore* cell) + void Scene::unloadCell(CellStore* cell) { - assert(mActiveCells.find(cell) == mActiveCells.end()); - assert(mInactiveCells.find(cell) != mInactiveCells.end()); - - Log(Debug::Info) << "Unloading cell " << cell->getCell()->getDescription(); - - ListObjectsVisitor visitor; - - cell->forEach(visitor); - for (const auto& ptr : visitor.mObjects) - { - mPhysics->remove(ptr); - ptr.mRef->mData.mPhysicsPostponed = false; - } - - if (cell->getCell()->isExterior()) - { - const auto cellX = cell->getCell()->getGridX(); - const auto cellY = cell->getCell()->getGridY(); - mPhysics->removeHeightField(cellX, cellY); - } - - mInactiveCells.erase(cell); - } - - void Scene::deactivateCell(CellStore* cell) - { - assert(mInactiveCells.find(cell) != mInactiveCells.end()); if (mActiveCells.find(cell) == mActiveCells.end()) return; - Log(Debug::Info) << "Deactivate cell " << cell->getCell()->getDescription(); + Log(Debug::Info) << "Unloading cell " << cell->getCell()->getDescription(); ListAndResetObjectsVisitor visitor; @@ -367,8 +322,8 @@ namespace MWWorld if (const auto object = mPhysics->getObject(ptr)) { mNavigator.removeObject(DetourNavigator::ObjectId(object)); - if (object->isAnimated()) - mPhysics->remove(ptr); + mPhysics->remove(ptr); + ptr.mRef->mData.mPhysicsPostponed = false; } else if (mPhysics->getActor(ptr)) { @@ -386,6 +341,8 @@ namespace MWWorld { if (mPhysics->getHeightField(cellX, cellY) != nullptr) mNavigator.removeHeightfield(osg::Vec2i(cellX, cellY)); + + mPhysics->removeHeightField(cellX, cellY); } if (cell->getCell()->hasWater()) @@ -408,12 +365,11 @@ namespace MWWorld mActiveCells.erase(cell); } - void Scene::activateCell(CellStore *cell, Loading::Listener* loadingListener, bool respawn) + void Scene::loadCell(CellStore *cell, Loading::Listener* loadingListener, bool respawn) { using DetourNavigator::HeightfieldShape; assert(mActiveCells.find(cell) == mActiveCells.end()); - assert(mInactiveCells.find(cell) != mInactiveCells.end()); mActiveCells.insert(cell); Log(Debug::Info) << "Loading cell " << cell->getCell()->getDescription(); @@ -425,13 +381,25 @@ namespace MWWorld if (cell->getCell()->isExterior()) { + osg::ref_ptr land = mRendering.getLandManager()->getLand(cellX, cellY); + const ESM::Land::LandData* data = land ? land->getData(ESM::Land::DATA_VHGT) : nullptr; + const float verts = ESM::Land::LAND_SIZE; + const float worldsize = ESM::Land::REAL_SIZE; + if (data) + { + mPhysics->addHeightField (data->mHeights, cellX, cellY, worldsize / (verts-1), verts, data->mMinHeight, data->mMaxHeight, land.get()); + } + else + { + static std::vector defaultHeight; + defaultHeight.resize(verts*verts, ESM::Land::DEFAULT_HEIGHT); + mPhysics->addHeightField (&defaultHeight[0], cellX, cellY, worldsize / (verts-1), 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 osg::ref_ptr land = mRendering.getLandManager()->getLand(cellX, cellY); - const ESM::Land::LandData* const data = land == nullptr ? nullptr : land->getData(ESM::Land::DATA_VHGT); const HeightfieldShape shape = [&] () -> HeightfieldShape { if (data == nullptr) @@ -462,7 +430,7 @@ namespace MWWorld if (respawn) cell->respawn(); - insertCell(*cell, loadingListener, false); + insertCell(*cell, loadingListener); mRendering.addCell(cell); @@ -511,49 +479,14 @@ namespace MWWorld mPreloader->notifyLoaded(cell); } - void Scene::loadInactiveCell(CellStore *cell, Loading::Listener* loadingListener) - { - assert(mActiveCells.find(cell) == mActiveCells.end()); - assert(mInactiveCells.find(cell) == mInactiveCells.end()); - mInactiveCells.insert(cell); - - Log(Debug::Info) << "Loading inactive cell " << cell->getCell()->getDescription(); - - if (cell->getCell()->isExterior()) - { - float verts = ESM::Land::LAND_SIZE; - float worldsize = ESM::Land::REAL_SIZE; - - const int cellX = cell->getCell()->getGridX(); - const int cellY = cell->getCell()->getGridY(); - - osg::ref_ptr land = mRendering.getLandManager()->getLand(cellX, cellY); - const ESM::Land::LandData* data = land ? land->getData(ESM::Land::DATA_VHGT) : nullptr; - if (data) - { - mPhysics->addHeightField (data->mHeights, cellX, cellY, worldsize / (verts-1), verts, data->mMinHeight, data->mMaxHeight, land.get()); - } - else - { - static std::vector defaultHeight; - defaultHeight.resize(verts*verts, ESM::Land::DEFAULT_HEIGHT); - mPhysics->addHeightField (&defaultHeight[0], cellX, cellY, worldsize / (verts-1), verts, ESM::Land::DEFAULT_HEIGHT, ESM::Land::DEFAULT_HEIGHT, land.get()); - } - } - - insertCell(*cell, loadingListener, true); - } - void Scene::clear() { - for (auto iter = mInactiveCells.begin(); iter!=mInactiveCells.end(); ) + for (auto iter = mActiveCells.begin(); iter!=mActiveCells.end(); ) { auto* cell = *iter++; - deactivateCell(cell); - unloadInactiveCell (cell); + unloadCell (cell); } assert(mActiveCells.empty()); - assert(mInactiveCells.empty()); mCurrentCell = nullptr; mPreloader->clear(); @@ -595,7 +528,7 @@ namespace MWWorld void Scene::changeCellGrid (const osg::Vec3f &pos, int playerCellX, int playerCellY, bool changeEvent) { - for (auto iter = mInactiveCells.begin(); iter != mInactiveCells.end(); ) + for (auto iter = mActiveCells.begin(); iter != mActiveCells.end(); ) { auto* cell = *iter++; if (cell->getCell()->isExterior()) @@ -603,16 +536,10 @@ namespace MWWorld const auto dx = std::abs(playerCellX - cell->getCell()->getGridX()); const auto dy = std::abs(playerCellY - cell->getCell()->getGridY()); if (dx > mHalfGridSize || dy > mHalfGridSize) - deactivateCell(cell); - - if (dx > mHalfGridSize+1 || dy > mHalfGridSize+1) - unloadInactiveCell(cell); + unloadCell(cell); } else - { - deactivateCell(cell); - unloadInactiveCell(cell); - } + unloadCell (cell); } mCurrentGridCenter = osg::Vec2i(playerCellX, playerCellY); @@ -662,7 +589,6 @@ namespace MWWorld } auto cellsPositionsToLoad = cellsToLoad(mActiveCells,mHalfGridSize); - auto cellsPositionsToLoadInactive = cellsToLoad(mInactiveCells,mHalfGridSize+1); Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen(); Loading::ScopedLoad load(loadingListener); @@ -685,26 +611,12 @@ namespace MWWorld return getCellPositionPriority(lhs) < getCellPositionPriority(rhs); }); - std::sort(cellsPositionsToLoadInactive.begin(), cellsPositionsToLoadInactive.end(), - [&] (const std::pair& lhs, const std::pair& rhs) { - return getCellPositionPriority(lhs) < getCellPositionPriority(rhs); - }); - - // Load cells - for (const auto& [x,y] : cellsPositionsToLoadInactive) - { - if (!isCellInCollection(x, y, mInactiveCells)) - { - CellStore *cell = MWBase::Environment::get().getWorld()->getExterior(x, y); - loadInactiveCell (cell, loadingListener); - } - } for (const auto& [x,y] : cellsPositionsToLoad) { if (!isCellInCollection(x, y, mActiveCells)) { CellStore *cell = MWBase::Environment::get().getWorld()->getExterior(x, y); - activateCell (cell, loadingListener, changeEvent); + loadCell (cell, loadingListener, changeEvent); } } @@ -737,17 +649,15 @@ namespace MWWorld loadingListener->setLabel("Testing exterior cells ("+std::to_string(i)+"/"+std::to_string(cells.getExtSize())+")..."); CellStore *cell = MWBase::Environment::get().getWorld()->getExterior(it->mData.mX, it->mData.mY); - loadInactiveCell(cell, nullptr); - activateCell(cell, nullptr, false); + loadCell(cell, nullptr, false); - auto iter = mInactiveCells.begin(); - while (iter != mInactiveCells.end()) + auto iter = mActiveCells.begin(); + while (iter != mActiveCells.end()) { if (it->isExterior() && it->mData.mX == (*iter)->getCell()->getGridX() && it->mData.mY == (*iter)->getCell()->getGridY()) { - deactivateCell(*iter); - unloadInactiveCell(*iter); + unloadCell(*iter); break; } @@ -785,18 +695,16 @@ namespace MWWorld loadingListener->setLabel("Testing interior cells ("+std::to_string(i)+"/"+std::to_string(cells.getIntSize())+")..."); CellStore *cell = MWBase::Environment::get().getWorld()->getInterior(it->mName); - loadInactiveCell(cell, nullptr); - activateCell(cell, nullptr, false); + loadCell(cell, nullptr, false); - auto iter = mInactiveCells.begin(); - while (iter != mInactiveCells.end()) + auto iter = mActiveCells.begin(); + while (iter != mActiveCells.end()) { assert (!(*iter)->getCell()->isExterior()); if (it->mName == (*iter)->getCell()->mName) { - deactivateCell(*iter); - unloadInactiveCell(*iter); + unloadCell(*iter); break; } @@ -915,11 +823,10 @@ namespace MWWorld Log(Debug::Info) << "Changing to interior"; // unload - for (auto iter = mInactiveCells.begin(); iter!=mInactiveCells.end(); ) + for (auto iter = mActiveCells.begin(); iter!=mActiveCells.end(); ) { auto* cellToUnload = *iter++; - deactivateCell(cellToUnload); - unloadInactiveCell(cellToUnload); + unloadCell(cellToUnload); } assert(mActiveCells.empty()); assert(mInactiveCells.empty()); @@ -928,8 +835,7 @@ namespace MWWorld // Load cell. mPagedRefs.clear(); - loadInactiveCell (cell, loadingListener); - activateCell (cell, loadingListener, changeEvent); + loadCell(cell, loadingListener, changeEvent); changePlayerCell(cell, position, adjustPlayerPos); @@ -979,26 +885,19 @@ namespace MWWorld mCellChanged = false; } - void Scene::insertCell (CellStore &cell, Loading::Listener* loadingListener, bool onlyObjects) + void Scene::insertCell (CellStore &cell, Loading::Listener* loadingListener) { - InsertVisitor insertVisitor(cell, loadingListener, onlyObjects); + InsertVisitor insertVisitor(cell, loadingListener); cell.forEach (insertVisitor); - insertVisitor.insert([&] (const MWWorld::Ptr& ptr) { addObject(ptr, *mPhysics, mRendering, mPagedRefs, onlyObjects); }); - if (!onlyObjects) - { - insertVisitor.insert([&] (const MWWorld::Ptr& ptr) { addObject(ptr, *mPhysics, mNavigator); }); - - // do adjustPosition (snapping actors to ground) after objects are loaded, so we don't depend on the loading order - PositionVisitor posVisitor; - cell.forEach (posVisitor); - } + insertVisitor.insert([&] (const MWWorld::Ptr& ptr) { addObject(ptr, *mPhysics, mRendering, mPagedRefs); }); + insertVisitor.insert([&] (const MWWorld::Ptr& ptr) { addObject(ptr, *mPhysics, mNavigator); }); } void Scene::addObjectToScene (const Ptr& ptr) { try { - addObject(ptr, *mPhysics, mRendering, mPagedRefs, false); + addObject(ptr, *mPhysics, mRendering, mPagedRefs); addObject(ptr, *mPhysics, mNavigator); MWBase::Environment::get().getWorld()->scaleObject(ptr, ptr.getCellRef().getScale()); const auto player = MWBase::Environment::get().getWorld()->getPlayerPtr(); diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp index 3f5d7bf2f5..12d79d3d11 100644 --- a/apps/openmw/mwworld/scene.hpp +++ b/apps/openmw/mwworld/scene.hpp @@ -77,7 +77,6 @@ namespace MWWorld CellStore* mCurrentCell; // the cell the player is in CellStoreCollection mActiveCells; - CellStoreCollection mInactiveCells; bool mCellChanged; MWPhysics::PhysicsSystem *mPhysics; MWRender::RenderingManager& mRendering; @@ -100,7 +99,7 @@ namespace MWWorld std::vector> mWorkItems; - void insertCell(CellStore &cell, Loading::Listener* loadingListener, bool onlyObjects); + void insertCell(CellStore &cell, Loading::Listener* loadingListener); osg::Vec2i mCurrentGridCenter; // Load and unload cells as necessary to create a cell grid with "X" and "Y" in the center @@ -116,10 +115,8 @@ namespace MWWorld osg::Vec4i gridCenterToBounds(const osg::Vec2i ¢erCell) const; osg::Vec2i getNewGridCenter(const osg::Vec3f &pos, const osg::Vec2i *currentGridCenter = nullptr) const; - void unloadInactiveCell(CellStore* cell); - void deactivateCell(CellStore* cell); - void activateCell(CellStore *cell, Loading::Listener* loadingListener, bool respawn); - void loadInactiveCell(CellStore *cell, Loading::Listener* loadingListener); + void unloadCell(CellStore* cell); + void loadCell(CellStore *cell, Loading::Listener* loadingListener, bool respawn); public: