From 1218e4e15d778c91430e91afb4ff580180797950 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 3 Mar 2019 14:58:03 +0300 Subject: [PATCH 1/7] Use player half extents only to find path in exterior cells --- apps/openmw/mwbase/world.hpp | 4 ++++ apps/openmw/mwmechanics/aipackage.cpp | 4 ++-- apps/openmw/mwmechanics/aiwander.cpp | 9 ++++----- apps/openmw/mwworld/player.cpp | 6 ++++++ apps/openmw/mwworld/player.hpp | 2 ++ apps/openmw/mwworld/scene.cpp | 18 ++++++------------ apps/openmw/mwworld/worldimp.cpp | 17 +++++++++++++++-- apps/openmw/mwworld/worldimp.hpp | 4 ++++ 8 files changed, 43 insertions(+), 21 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 217e6d367..4b9467e50 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -134,6 +134,7 @@ namespace MWBase virtual MWWorld::Player& getPlayer() = 0; virtual MWWorld::Ptr getPlayerPtr() = 0; + virtual MWWorld::ConstPtr getPlayerConstPtr() const = 0; virtual const MWWorld::ESMStore& getStore() const = 0; @@ -615,6 +616,9 @@ namespace MWBase virtual void removeActorPath(const MWWorld::ConstPtr& actor) const = 0; virtual void setNavMeshNumberToRender(const std::size_t value) = 0; + + /// Return physical half extents of the given actor to be used in pathfinding + virtual osg::Vec3f getPathfindingHalfExtents(const MWWorld::ConstPtr& actor) const = 0; }; } diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index 91449498d..0fa92c301 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -135,9 +135,9 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& { if (wasShortcutting || doesPathNeedRecalc(dest, actor.getCell())) // if need to rebuild path { - const osg::Vec3f playerHalfExtents = world->getHalfExtents(getPlayer()); // Using player half extents for better performance + const auto halfExtents = world->getPathfindingHalfExtents(actor); mPathFinder.buildPath(actor, position, dest, actor.getCell(), getPathGridGraph(actor.getCell()), - playerHalfExtents, getNavigatorFlags(actor)); + halfExtents, getNavigatorFlags(actor)); mRotateOnTheRunChecks = 3; // give priority to go directly on target if there is minimal opportunity diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 05465c6b0..405f36767 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -155,9 +155,9 @@ namespace MWMechanics } else { - const osg::Vec3f playerHalfExtents = MWBase::Environment::get().getWorld()->getHalfExtents(getPlayer()); // Using player half extents for better performance + const osg::Vec3f halfExtents = MWBase::Environment::get().getWorld()->getPathfindingHalfExtents(actor); mPathFinder.buildPath(actor, pos.asVec3(), mDestination, actor.getCell(), - getPathGridGraph(actor.getCell()), playerHalfExtents, getNavigatorFlags(actor)); + getPathGridGraph(actor.getCell()), halfExtents, getNavigatorFlags(actor)); } if (mPathFinder.isPathConstructed()) @@ -312,10 +312,9 @@ namespace MWMechanics if ((!isWaterCreature && !destinationIsAtWater(actor, mDestination)) || (isWaterCreature && !destinationThroughGround(currentPosition, mDestination))) { - // Using player half extents for better performance - const osg::Vec3f playerHalfExtents = MWBase::Environment::get().getWorld()->getHalfExtents(getPlayer()); + const osg::Vec3f halfExtents = MWBase::Environment::get().getWorld()->getPathfindingHalfExtents(actor); mPathFinder.buildPath(actor, currentPosition, mDestination, actor.getCell(), - getPathGridGraph(actor.getCell()), playerHalfExtents, getNavigatorFlags(actor)); + getPathGridGraph(actor.getCell()), halfExtents, getNavigatorFlags(actor)); mPathFinder.addPointToPath(mDestination); if (mPathFinder.isPathConstructed()) diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index f152b2cae..9e2d9d6ff 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -122,6 +122,12 @@ namespace MWWorld return ptr; } + MWWorld::ConstPtr Player::getConstPlayer() const + { + MWWorld::ConstPtr ptr (&mPlayer, mCellStore); + return ptr; + } + void Player::setBirthSign (const std::string &sign) { mSign = sign; diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index e2632f210..96ed20adf 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -27,6 +27,7 @@ namespace Loading namespace MWWorld { class CellStore; + class ConstPtr; /// \brief NPC object representing the player and additional player data class Player @@ -81,6 +82,7 @@ namespace MWWorld void setCell (MWWorld::CellStore *cellStore); MWWorld::Ptr getPlayer(); + MWWorld::ConstPtr getConstPlayer() const; void setBirthSign(const std::string &sign); const std::string &getBirthSign() const; diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 1e8418893..d06034e1d 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -172,12 +172,9 @@ namespace ); } } - else if (const auto actor = physics.getActor(ptr)) + else if (physics.getActor(ptr)) { - const auto halfExtents = ptr.getCell()->isExterior() - ? physics.getHalfExtents(MWBase::Environment::get().getWorld()->getPlayerPtr()) - : actor->getHalfExtents(); - navigator.addAgent(halfExtents); + navigator.addAgent(MWBase::Environment::get().getWorld()->getPathfindingHalfExtents(ptr)); } } @@ -337,15 +334,14 @@ namespace MWWorld ListAndResetObjectsVisitor visitor; (*iter)->forEach(visitor); - const auto player = MWBase::Environment::get().getWorld()->getPlayerPtr(); - const auto playerHalfExtents = mPhysics->getHalfExtents(player); + const auto world = MWBase::Environment::get().getWorld(); for (const auto& ptr : visitor.mObjects) { if (const auto object = mPhysics->getObject(ptr)) navigator->removeObject(DetourNavigator::ObjectId(object)); else if (const auto actor = mPhysics->getActor(ptr)) { - navigator->removeAgent(ptr.getCell()->isExterior() ? playerHalfExtents : actor->getHalfExtents()); + navigator->removeAgent(world->getPathfindingHalfExtents(ptr)); mRendering.removeActorPath(ptr); } mPhysics->remove(ptr); @@ -372,6 +368,7 @@ namespace MWWorld if ((*iter)->getCell()->hasWater()) navigator->removeWater(osg::Vec2i(cellX, cellY)); + const auto player = world->getPlayerPtr(); navigator->update(player.getRefData().getPosition().asVec3()); MWBase::Environment::get().getMechanicsManager()->drop (*iter); @@ -815,10 +812,7 @@ namespace MWWorld } else if (const auto actor = mPhysics->getActor(ptr)) { - const auto& halfExtents = ptr.getCell()->isExterior() - ? mPhysics->getHalfExtents(MWBase::Environment::get().getWorld()->getPlayerPtr()) - : actor->getHalfExtents(); - navigator->removeAgent(halfExtents); + navigator->removeAgent(MWBase::Environment::get().getWorld()->getPathfindingHalfExtents(ptr)); } mPhysics->remove(ptr); mRendering.removeObject (ptr); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 502ff8843..fa394cc10 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2408,7 +2408,7 @@ namespace MWWorld { // Remove the old CharacterController MWBase::Environment::get().getMechanicsManager()->remove(getPlayerPtr()); - mNavigator->removeAgent(mPhysics->getHalfExtents(getPlayerPtr())); + mNavigator->removeAgent(getPathfindingHalfExtents(getPlayerConstPtr())); mPhysics->remove(getPlayerPtr()); mRendering->removePlayer(getPlayerPtr()); @@ -2443,7 +2443,7 @@ namespace MWWorld applyLoopingParticles(player); - mNavigator->addAgent(mPhysics->getHalfExtents(getPlayerPtr())); + mNavigator->addAgent(getPathfindingHalfExtents(getPlayerConstPtr())); } World::RestPermitted World::canRest () const @@ -3418,6 +3418,11 @@ namespace MWWorld return mPlayer->getPlayer(); } + MWWorld::ConstPtr World::getPlayerConstPtr() const + { + return mPlayer->getConstPlayer(); + } + void World::updateDialogueGlobals() { MWWorld::Ptr player = getPlayerPtr(); @@ -3787,4 +3792,12 @@ namespace MWWorld mRendering->setNavMeshNumber(value); } + osg::Vec3f World::getPathfindingHalfExtents(const MWWorld::ConstPtr& actor) const + { + if (actor.isInCell() && actor.getCell()->isExterior()) + return getHalfExtents(getPlayerConstPtr()); // Using player half extents for better performance + else + return getHalfExtents(actor); + } + } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 98e82bb86..71d6c5afd 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -238,6 +238,7 @@ namespace MWWorld Player& getPlayer() override; MWWorld::Ptr getPlayerPtr() override; + MWWorld::ConstPtr getPlayerConstPtr() const override; const MWWorld::ESMStore& getStore() const override; @@ -717,6 +718,9 @@ namespace MWWorld void removeActorPath(const MWWorld::ConstPtr& actor) const override; void setNavMeshNumberToRender(const std::size_t value) override; + + /// Return physical half extents of the given actor to be used in pathfinding + osg::Vec3f getPathfindingHalfExtents(const MWWorld::ConstPtr& actor) const override; }; } From 43b39e841816814e74cf49870439a4c5396c516c Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 3 Mar 2019 14:45:36 +0300 Subject: [PATCH 2/7] Use not scaled player half extents as default to find path --- apps/openmw/mwphysics/actor.cpp | 5 +++++ apps/openmw/mwphysics/actor.hpp | 5 +++++ apps/openmw/mwphysics/physicssystem.cpp | 8 ++++++++ apps/openmw/mwphysics/physicssystem.hpp | 3 +++ apps/openmw/mwworld/worldimp.cpp | 3 ++- apps/openmw/mwworld/worldimp.hpp | 2 ++ 6 files changed, 25 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 632d32c26..0f8814aca 100644 --- a/apps/openmw/mwphysics/actor.cpp +++ b/apps/openmw/mwphysics/actor.cpp @@ -201,6 +201,11 @@ osg::Vec3f Actor::getHalfExtents() const return osg::componentMultiply(mHalfExtents, mScale); } +osg::Vec3f Actor::getOriginalHalfExtents() const +{ + return mHalfExtents; +} + osg::Vec3f Actor::getRenderingHalfExtents() const { return osg::componentMultiply(mHalfExtents, mRenderingScale); diff --git a/apps/openmw/mwphysics/actor.hpp b/apps/openmw/mwphysics/actor.hpp index 31dd22a22..8752f7fee 100644 --- a/apps/openmw/mwphysics/actor.hpp +++ b/apps/openmw/mwphysics/actor.hpp @@ -66,6 +66,11 @@ namespace MWPhysics */ osg::Vec3f getHalfExtents() const; + /** + * Returns the half extents of the collision body (not scaled) + */ + osg::Vec3f getOriginalHalfExtents() const; + /** * Returns the position of the collision body * @note The collision shape's origin is in its center, so the position returned can be described as center of the actor collision box in world space. diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index d12f7fe6c..e3884afad 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -906,6 +906,14 @@ namespace MWPhysics return osg::Vec3f(); } + osg::Vec3f PhysicsSystem::getOriginalHalfExtents(const MWWorld::ConstPtr &actor) const + { + if (const Actor* physactor = getActor(actor)) + return physactor->getOriginalHalfExtents(); + else + return osg::Vec3f(); + } + osg::Vec3f PhysicsSystem::getRenderingHalfExtents(const MWWorld::ConstPtr &actor) const { const Actor* physactor = getActor(actor); diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index 76fbcf8c6..364a59ab1 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -136,6 +136,9 @@ namespace MWPhysics /// Get physical half extents (scaled) of the given actor. osg::Vec3f getHalfExtents(const MWWorld::ConstPtr& actor) const; + /// Get physical half extents (not scaled) of the given actor. + osg::Vec3f getOriginalHalfExtents(const MWWorld::ConstPtr& actor) const; + /// @see MWPhysics::Actor::getRenderingHalfExtents osg::Vec3f getRenderingHalfExtents(const MWWorld::ConstPtr& actor) const; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index fa394cc10..eb401658e 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2443,6 +2443,7 @@ namespace MWWorld applyLoopingParticles(player); + mDefaultHalfExtents = mPhysics->getOriginalHalfExtents(getPlayerPtr()); mNavigator->addAgent(getPathfindingHalfExtents(getPlayerConstPtr())); } @@ -3795,7 +3796,7 @@ namespace MWWorld osg::Vec3f World::getPathfindingHalfExtents(const MWWorld::ConstPtr& actor) const { if (actor.isInCell() && actor.getCell()->isExterior()) - return getHalfExtents(getPlayerConstPtr()); // Using player half extents for better performance + return mDefaultHalfExtents; // Using default half extents for better performance else return getHalfExtents(actor); } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 71d6c5afd..f0c28ea9e 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -111,6 +111,8 @@ namespace MWWorld std::string mUserDataPath; + osg::Vec3f mDefaultHalfExtents; + // not implemented World (const World&); World& operator= (const World&); From 2e063d59cef22c35cad3de5e70e568e270161ed3 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 3 Mar 2019 15:14:51 +0300 Subject: [PATCH 3/7] Update scaled agent half extents in navigator (bug #4763) --- apps/openmw/mwworld/worldimp.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index eb401658e..c0e79352f 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1328,9 +1328,15 @@ namespace MWWorld void World::scaleObject (const Ptr& ptr, float scale) { + if (mPhysics->getActor(ptr)) + mNavigator->removeAgent(getPathfindingHalfExtents(ptr)); + ptr.getCellRef().setScale(scale); mWorldScene->updateObjectScale(ptr); + + if (mPhysics->getActor(ptr)) + mNavigator->addAgent(getPathfindingHalfExtents(ptr)); } void World::rotateObjectImp (const Ptr& ptr, const osg::Vec3f& rot, bool adjust) From 27d74522677ea3b95e37b5d44ce254c36c2835b0 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 3 Mar 2019 15:51:02 +0300 Subject: [PATCH 4/7] Update scaled objects in navigator --- apps/openmw/mwworld/worldimp.cpp | 13 ++++++++----- apps/openmw/mwworld/worldimp.hpp | 1 + .../detournavigator/recastmeshobject.cpp | 7 +++++++ components/detournavigator/recastmeshobject.cpp | 6 ++++++ components/detournavigator/recastmeshobject.hpp | 1 + 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index c0e79352f..74d4d2838 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1337,6 +1337,8 @@ namespace MWWorld if (mPhysics->getActor(ptr)) mNavigator->addAgent(getPathfindingHalfExtents(ptr)); + else if (const auto object = mPhysics->getObject(ptr)) + mShouldUpdateNavigator = updateNavigatorObject(object) || mShouldUpdateNavigator; } void World::rotateObjectImp (const Ptr& ptr, const osg::Vec3f& rot, bool adjust) @@ -1570,19 +1572,20 @@ namespace MWWorld void World::updateNavigator() { - bool updated = false; - mPhysics->forEachAnimatedObject([&] (const MWPhysics::Object* object) { - updated = updateNavigatorObject(object) || updated; + mShouldUpdateNavigator = updateNavigatorObject(object) || mShouldUpdateNavigator; }); for (const auto& door : mDoorStates) if (const auto object = mPhysics->getObject(door.first)) - updated = updateNavigatorObject(object) || updated; + mShouldUpdateNavigator = updateNavigatorObject(object) || mShouldUpdateNavigator; - if (updated) + if (mShouldUpdateNavigator) + { mNavigator->update(getPlayerPtr().getRefData().getPosition().asVec3()); + mShouldUpdateNavigator = false; + } } bool World::updateNavigatorObject(const MWPhysics::Object* object) diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index f0c28ea9e..45653ded2 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -112,6 +112,7 @@ namespace MWWorld std::string mUserDataPath; osg::Vec3f mDefaultHalfExtents; + bool mShouldUpdateNavigator = false; // not implemented World (const World&); diff --git a/apps/openmw_test_suite/detournavigator/recastmeshobject.cpp b/apps/openmw_test_suite/detournavigator/recastmeshobject.cpp index 9b30cadd7..a3606f827 100644 --- a/apps/openmw_test_suite/detournavigator/recastmeshobject.cpp +++ b/apps/openmw_test_suite/detournavigator/recastmeshobject.cpp @@ -69,4 +69,11 @@ namespace object.update(mTransform, AreaType_ground); EXPECT_FALSE(object.update(mTransform, AreaType_ground)); } + + TEST_F(DetourNavigatorRecastMeshObjectTest, update_for_changed_local_scaling_should_return_true) + { + RecastMeshObject object(mBoxShape, mTransform, AreaType_ground); + mBoxShape.setLocalScaling(btVector3(2, 2, 2)); + EXPECT_TRUE(object.update(mTransform, AreaType_ground)); + } } diff --git a/components/detournavigator/recastmeshobject.cpp b/components/detournavigator/recastmeshobject.cpp index 24d3e6b5a..aac0b4c3c 100644 --- a/components/detournavigator/recastmeshobject.cpp +++ b/components/detournavigator/recastmeshobject.cpp @@ -13,6 +13,7 @@ namespace DetourNavigator : mShape(shape) , mTransform(transform) , mAreaType(areaType) + , mLocalScaling(shape.getLocalScaling()) , mChildren(makeChildrenObjects(shape, mAreaType)) { } @@ -30,6 +31,11 @@ namespace DetourNavigator mAreaType = areaType; result = true; } + if (!(mLocalScaling == mShape.get().getLocalScaling())) + { + mLocalScaling = mShape.get().getLocalScaling(); + result = true; + } if (mShape.get().isCompound()) result = updateCompoundObject(static_cast(mShape.get()), mAreaType, mChildren) || result; diff --git a/components/detournavigator/recastmeshobject.hpp b/components/detournavigator/recastmeshobject.hpp index aff468122..f25647ae5 100644 --- a/components/detournavigator/recastmeshobject.hpp +++ b/components/detournavigator/recastmeshobject.hpp @@ -39,6 +39,7 @@ namespace DetourNavigator std::reference_wrapper mShape; btTransform mTransform; AreaType mAreaType; + btVector3 mLocalScaling; std::vector mChildren; static bool updateCompoundObject(const btCompoundShape& shape, const AreaType areaType, From 8c08c3c7d6d6d75670554b91ff70614c8a581ea6 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 3 Mar 2019 15:59:02 +0300 Subject: [PATCH 5/7] Update moved objects in navigator --- apps/openmw/mwworld/worldimp.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 74d4d2838..895a6c198 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1298,6 +1298,9 @@ namespace MWWorld { mPhysics->updatePosition(newPtr); mPhysics->updatePtr(ptr, newPtr); + + if (const auto object = mPhysics->getObject(newPtr)) + updateNavigatorObject(object); } } if (isPlayer) From 80051db8f83b494583ba04988e2e91794e89de1a Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 3 Mar 2019 16:01:52 +0300 Subject: [PATCH 6/7] Update rotated objects in navigator --- apps/openmw/mwworld/worldimp.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 895a6c198..72e143358 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1381,7 +1381,12 @@ namespace MWWorld ptr.getRefData().setPosition(pos); if(ptr.getRefData().getBaseNode() != 0) + { mWorldScene->updateObjectRotation(ptr, true); + + if (const auto object = mPhysics->getObject(ptr)) + updateNavigatorObject(object); + } } void World::adjustPosition(const Ptr &ptr, bool force) From 84fbb486d3f534ef357a440a71ac9e3c8d0b4bde Mon Sep 17 00:00:00 2001 From: elsid Date: Mon, 4 Mar 2019 22:51:31 +0300 Subject: [PATCH 7/7] Fix switch from invalid navmesh number to valid --- apps/openmw/mwrender/navmesh.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/navmesh.cpp b/apps/openmw/mwrender/navmesh.cpp index 331f506ab..bfc80914a 100644 --- a/apps/openmw/mwrender/navmesh.cpp +++ b/apps/openmw/mwrender/navmesh.cpp @@ -34,7 +34,7 @@ namespace MWRender void NavMesh::update(const dtNavMesh& navMesh, const std::size_t id, const std::size_t generation, const std::size_t revision, const DetourNavigator::Settings& settings) { - if (!mEnabled || (mId == id && mGeneration >= generation && mRevision >= revision)) + if (!mEnabled || (mGroup && mId == id && mGeneration >= generation && mRevision >= revision)) return; mId = id; @@ -53,7 +53,10 @@ namespace MWRender void NavMesh::reset() { if (mGroup) + { mRootNode->removeChild(mGroup); + mGroup = nullptr; + } } void NavMesh::enable() @@ -65,7 +68,8 @@ namespace MWRender void NavMesh::disable() { - reset(); + if (mGroup) + mRootNode->removeChild(mGroup); mEnabled = false; } }