Merge pull request #2550 from elsid/fix_path_rebuild

Fix rebuild path for walking actors (Bug #5181)
pull/556/head
Alexei Dobrohotov 5 years ago committed by GitHub
commit 5d5ec1cf63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -133,7 +133,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f&
if (!mIsShortcutting)
{
if (wasShortcutting || doesPathNeedRecalc(dest, actor.getCell())) // if need to rebuild path
if (wasShortcutting || doesPathNeedRecalc(dest, actor)) // if need to rebuild path
{
const auto pathfindingHalfExtents = world->getPathfindingHalfExtents(actor);
mPathFinder.buildPath(actor, position, dest, actor.getCell(), getPathGridGraph(actor.getCell()),
@ -328,11 +328,11 @@ bool MWMechanics::AiPackage::checkWayIsClearForActor(const osg::Vec3f& startPoin
return false;
}
bool MWMechanics::AiPackage::doesPathNeedRecalc(const osg::Vec3f& newDest, const MWWorld::CellStore* currentCell)
bool MWMechanics::AiPackage::doesPathNeedRecalc(const osg::Vec3f& newDest, const MWWorld::Ptr& actor) const
{
return mPathFinder.getPath().empty()
|| (distance(mPathFinder.getPath().back(), newDest) > 10)
|| mPathFinder.getPathCell() != currentCell;
|| getPathDistance(actor, mPathFinder.getPath().back(), newDest) > 10
|| mPathFinder.getPathCell() != actor.getCell();
}
bool MWMechanics::AiPackage::isNearInactiveCell(osg::Vec3f position)

@ -120,7 +120,7 @@ namespace MWMechanics
/// Check if the way to the destination is clear, taking into account actor speed
bool checkWayIsClearForActor(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, const MWWorld::Ptr& actor);
bool doesPathNeedRecalc(const osg::Vec3f& newDest, const MWWorld::CellStore* currentCell);
bool doesPathNeedRecalc(const osg::Vec3f& newDest, const MWWorld::Ptr& actor) const;
void evadeObstacles(const MWWorld::Ptr& actor);

@ -20,6 +20,7 @@
#include "spellcasting.hpp"
#include "difficultyscaling.hpp"
#include "actorutil.hpp"
#include "pathfinding.hpp"
namespace
{
@ -467,13 +468,8 @@ namespace MWMechanics
{
osg::Vec3f pos1 (actor1.getRefData().getPosition().asVec3());
osg::Vec3f pos2 (actor2.getRefData().getPosition().asVec3());
if (canActorMoveByZAxis(actor2))
{
pos1.z() = 0.f;
pos2.z() = 0.f;
}
float d = (pos1 - pos2).length();
float d = getAggroDistance(actor2, pos1, pos2);
static const int iFightDistanceBase = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
"iFightDistanceBase")->mValue.getInteger();
@ -489,4 +485,11 @@ namespace MWMechanics
return (magicEffects.get(ESM::MagicEffect::Invisibility).getMagnitude() > 0)
|| (magicEffects.get(ESM::MagicEffect::Chameleon).getMagnitude() > 75);
}
float getAggroDistance(const MWWorld::Ptr& actor, const osg::Vec3f& lhs, const osg::Vec3f& rhs)
{
if (canActorMoveByZAxis(actor))
return distanceIgnoreZ(lhs, rhs);
return distance(lhs, rhs);
}
}

@ -55,6 +55,9 @@ void applyFatigueLoss(const MWWorld::Ptr& attacker, const MWWorld::Ptr& weapon,
float getFightDistanceBias(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2);
bool isTargetMagicallyHidden(const MWWorld::Ptr& target);
float getAggroDistance(const MWWorld::Ptr& actor, const osg::Vec3f& lhs, const osg::Vec3f& rhs);
}
#endif

@ -18,6 +18,7 @@
#include "pathgrid.hpp"
#include "coordinateconverter.hpp"
#include "actorutil.hpp"
namespace
{
@ -80,10 +81,24 @@ namespace
const auto realHalfExtents = world->getHalfExtents(actor);
return 2 * std::max(realHalfExtents.x(), realHalfExtents.y());
}
float getHeight(const MWWorld::ConstPtr& actor)
{
const auto world = MWBase::Environment::get().getWorld();
const auto halfExtents = world->getHalfExtents(actor);
return 2.0 * halfExtents.z();
}
}
namespace MWMechanics
{
float getPathDistance(const MWWorld::Ptr& actor, const osg::Vec3f& lhs, const osg::Vec3f& rhs)
{
if (std::abs(lhs.z() - rhs.z()) > getHeight(actor) || canActorMoveByZAxis(actor))
return distance(lhs, rhs);
return distanceIgnoreZ(lhs, rhs);
}
bool checkWayIsClear(const osg::Vec3f& from, const osg::Vec3f& to, float offsetXY)
{
osg::Vec3f dir = to - from;

@ -13,17 +13,29 @@ namespace MWWorld
{
class CellStore;
class ConstPtr;
class Ptr;
}
namespace MWMechanics
{
class PathgridGraph;
inline float distance(const osg::Vec3f& lhs, const osg::Vec3f& rhs)
template <class T>
inline float distance(const T& lhs, const T& rhs)
{
static_assert(std::is_same<T, osg::Vec2f>::value
|| std::is_same<T, osg::Vec3f>::value,
"T is not a position");
return (lhs - rhs).length();
}
inline float distanceIgnoreZ(const osg::Vec3f& lhs, const osg::Vec3f& rhs)
{
return distance(osg::Vec2f(lhs.x(), lhs.y()), osg::Vec2f(rhs.x(), rhs.y()));
}
float getPathDistance(const MWWorld::Ptr& actor, const osg::Vec3f& lhs, const osg::Vec3f& rhs);
inline float getZAngleToDir(const osg::Vec3f& dir)
{
return std::atan2(dir.x(), dir.y());

@ -176,12 +176,12 @@ recast scale factor
:Type: floating point
:Range: > 0.0
:Default: 0.017647058823529415
:Default: 0.023529411764705882
Scale of nav mesh coordinates to world coordinates. Recastnavigation builds voxels for world geometry.
Basically voxel size is 1 / "cell size". To reduce amount of voxels we apply scale factor, to make voxel size
"recast scale factor" / "cell size". Default value calculates by this equation:
sStepSizeUp * "recast scale factor" / "cell size" = 3 (max climb height should be equal to 3 voxels).
sStepSizeUp * "recast scale factor" / "cell size" = 4 (max climb height should be equal to 4 voxels).
Changing this value will change generated nav mesh. Some locations may become unavailable for NPC and creatures.
Pay attention to slopes and roofs when change it. Increasing this value will reduce nav mesh update latency.

@ -642,8 +642,8 @@ enable = true
# Scale of NavMesh coordinates to world coordinates (value > 0.0). Recastnavigation builds voxels for world geometry.
# Basically voxel size is 1 / "cell size". To reduce amount of voxels we apply scale factor, to make voxel size
# "recast scale factor" / "cell size". Default value calculates by this equation:
# sStepSizeUp * "recast scale factor" / "cell size" = 3 (max climb height should be equal to 3 voxels)
recast scale factor = 0.017647058823529415
# sStepSizeUp * "recast scale factor" / "cell size" = 4 (max climb height should be equal to 4 voxels)
recast scale factor = 0.023529411764705882
# The z-axis cell size to use for fields. (value > 0.0)
# Defines voxel/grid/cell size. So their values have significant
@ -711,12 +711,6 @@ max smooth path size = 1024
# Maximum number of triangles in each node of mesh AABB tree (value > 0)
triangles per chunk = 256
# Enable debug log (true, false)
enable log = false
# Write debug log to this file
log path = detournavigator.log
# Write recast mesh to file in .obj format for each use to update nav mesh (true, false)
enable write recast mesh to file = false

Loading…
Cancel
Save