From fdd84265b3fcc6b7790869287163d80c8078449e Mon Sep 17 00:00:00 2001 From: elsid Date: Wed, 15 Jun 2022 01:09:33 +0200 Subject: [PATCH] Use proper agent height and radius when render actor path That are based on half extents used to find path over navmesh which is different for interior and exterior cells. Use common functions to get agent height and radius for actor path rendering and navmesh generation. --- apps/openmw/mwmechanics/aipackage.cpp | 7 +++---- components/detournavigator/makenavmesh.cpp | 5 +++-- components/detournavigator/recastparams.hpp | 21 +++++++++++++++++++++ components/sceneutil/agentpath.cpp | 5 +++-- 4 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 components/detournavigator/recastparams.hpp diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index 7057a99393..24bfe41165 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -114,8 +114,6 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& const osg::Vec3f position = actor.getRefData().getPosition().asVec3(); //position of the actor MWBase::World* world = MWBase::Environment::get().getWorld(); - const osg::Vec3f halfExtents = world->getHalfExtents(actor); - /// Stops the actor when it gets too close to a unloaded cell //... At current time, this test is unnecessary. AI shuts down when actor is more than "actors processing range" setting value //... units from player, and exterior cells are 8192 units long and wide. @@ -124,7 +122,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& { actor.getClass().getMovementSettings(actor).mPosition[0] = 0; actor.getClass().getMovementSettings(actor).mPosition[1] = 0; - world->updateActorPath(actor, mPathFinder.getPath(), halfExtents, position, dest); + world->updateActorPath(actor, mPathFinder.getPath(), world->getPathfindingHalfExtents(actor), position, dest); return false; } @@ -180,6 +178,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& } } + const osg::Vec3f halfExtents = world->getHalfExtents(actor); const float pointTolerance = getPointTolerance(actor.getClass().getMaxSpeed(actor), duration, halfExtents); static const bool smoothMovement = Settings::Manager::getBool("smooth movement", "Game"); @@ -198,7 +197,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& else if (mPathFinder.getPath().empty()) return false; - world->updateActorPath(actor, mPathFinder.getPath(), halfExtents, position, dest); + world->updateActorPath(actor, mPathFinder.getPath(), world->getPathfindingHalfExtents(actor), position, dest); if (mRotateOnTheRunChecks == 0 || isReachableRotatingOnTheRun(actor, *mPathFinder.getPath().begin())) // to prevent circling around a path point diff --git a/components/detournavigator/makenavmesh.cpp b/components/detournavigator/makenavmesh.cpp index 070a227454..97c5377558 100644 --- a/components/detournavigator/makenavmesh.cpp +++ b/components/detournavigator/makenavmesh.cpp @@ -14,6 +14,7 @@ #include "serialization.hpp" #include "dbrefgeometryobject.hpp" #include "navmeshdbutils.hpp" +#include "recastparams.hpp" #include #include @@ -102,7 +103,7 @@ namespace float getHeight(const RecastSettings& settings,const osg::Vec3f& agentHalfExtents) { - return 2.0f * agentHalfExtents.z() * settings.mRecastScaleFactor; + return getAgentHeight(agentHalfExtents) * settings.mRecastScaleFactor; } float getMaxClimb(const RecastSettings& settings) @@ -112,7 +113,7 @@ namespace float getRadius(const RecastSettings& settings, const osg::Vec3f& agentHalfExtents) { - return std::max(agentHalfExtents.x(), agentHalfExtents.y()) * std::sqrt(2) * settings.mRecastScaleFactor; + return getAgentRadius(agentHalfExtents) * settings.mRecastScaleFactor; } float getSwimLevel(const RecastSettings& settings, const float waterLevel, const float agentHalfExtentsZ) diff --git a/components/detournavigator/recastparams.hpp b/components/detournavigator/recastparams.hpp new file mode 100644 index 0000000000..7e07d2c085 --- /dev/null +++ b/components/detournavigator/recastparams.hpp @@ -0,0 +1,21 @@ +#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_RECASTPARAMS_H +#define OPENMW_COMPONENTS_DETOURNAVIGATOR_RECASTPARAMS_H + +#include + +#include + +namespace DetourNavigator +{ + inline float getAgentHeight(const osg::Vec3f& agentHalfExtents) + { + return 2.0f * agentHalfExtents.z(); + } + + inline float getAgentRadius(const osg::Vec3f& agentHalfExtents) + { + return std::max(agentHalfExtents.x(), agentHalfExtents.y()) * std::sqrt(2); + } +} + +#endif diff --git a/components/sceneutil/agentpath.cpp b/components/sceneutil/agentpath.cpp index db026a3332..8d90475a82 100644 --- a/components/sceneutil/agentpath.cpp +++ b/components/sceneutil/agentpath.cpp @@ -4,6 +4,7 @@ #include #include +#include #include @@ -45,8 +46,8 @@ namespace SceneUtil DebugDraw debugDraw(*group, DebugDraw::makeStateSet(), osg::Vec3f(0, 0, 0), 1); - const auto agentRadius = halfExtents.x(); - const auto agentHeight = 2.0f * halfExtents.z(); + const auto agentRadius = DetourNavigator::getAgentRadius(halfExtents); + const auto agentHeight = DetourNavigator::getAgentHeight(halfExtents); const auto agentClimb = settings.mMaxClimb; const auto startColor = duRGBA(128, 25, 0, 192); const auto endColor = duRGBA(51, 102, 0, 129);