mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-30 07:21:12 +00:00
Merge pull request #2550 from elsid/fix_path_rebuild
Fix rebuild path for walking actors (Bug #5181)
This commit is contained in:
commit
5d5ec1cf63
@ -133,7 +133,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f&
|
|||||||
|
|
||||||
if (!mIsShortcutting)
|
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);
|
const auto pathfindingHalfExtents = world->getPathfindingHalfExtents(actor);
|
||||||
mPathFinder.buildPath(actor, position, dest, actor.getCell(), getPathGridGraph(actor.getCell()),
|
mPathFinder.buildPath(actor, position, dest, actor.getCell(), getPathGridGraph(actor.getCell()),
|
||||||
@ -328,11 +328,11 @@ bool MWMechanics::AiPackage::checkWayIsClearForActor(const osg::Vec3f& startPoin
|
|||||||
return false;
|
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()
|
return mPathFinder.getPath().empty()
|
||||||
|| (distance(mPathFinder.getPath().back(), newDest) > 10)
|
|| getPathDistance(actor, mPathFinder.getPath().back(), newDest) > 10
|
||||||
|| mPathFinder.getPathCell() != currentCell;
|
|| mPathFinder.getPathCell() != actor.getCell();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MWMechanics::AiPackage::isNearInactiveCell(osg::Vec3f position)
|
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
|
/// 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 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);
|
void evadeObstacles(const MWWorld::Ptr& actor);
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "spellcasting.hpp"
|
#include "spellcasting.hpp"
|
||||||
#include "difficultyscaling.hpp"
|
#include "difficultyscaling.hpp"
|
||||||
#include "actorutil.hpp"
|
#include "actorutil.hpp"
|
||||||
|
#include "pathfinding.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -467,13 +468,8 @@ namespace MWMechanics
|
|||||||
{
|
{
|
||||||
osg::Vec3f pos1 (actor1.getRefData().getPosition().asVec3());
|
osg::Vec3f pos1 (actor1.getRefData().getPosition().asVec3());
|
||||||
osg::Vec3f pos2 (actor2.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(
|
static const int iFightDistanceBase = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
||||||
"iFightDistanceBase")->mValue.getInteger();
|
"iFightDistanceBase")->mValue.getInteger();
|
||||||
@ -489,4 +485,11 @@ namespace MWMechanics
|
|||||||
return (magicEffects.get(ESM::MagicEffect::Invisibility).getMagnitude() > 0)
|
return (magicEffects.get(ESM::MagicEffect::Invisibility).getMagnitude() > 0)
|
||||||
|| (magicEffects.get(ESM::MagicEffect::Chameleon).getMagnitude() > 75);
|
|| (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);
|
float getFightDistanceBias(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2);
|
||||||
|
|
||||||
bool isTargetMagicallyHidden(const MWWorld::Ptr& target);
|
bool isTargetMagicallyHidden(const MWWorld::Ptr& target);
|
||||||
|
|
||||||
|
float getAggroDistance(const MWWorld::Ptr& actor, const osg::Vec3f& lhs, const osg::Vec3f& rhs);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "pathgrid.hpp"
|
#include "pathgrid.hpp"
|
||||||
#include "coordinateconverter.hpp"
|
#include "coordinateconverter.hpp"
|
||||||
|
#include "actorutil.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -80,10 +81,24 @@ namespace
|
|||||||
const auto realHalfExtents = world->getHalfExtents(actor);
|
const auto realHalfExtents = world->getHalfExtents(actor);
|
||||||
return 2 * std::max(realHalfExtents.x(), realHalfExtents.y());
|
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
|
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)
|
bool checkWayIsClear(const osg::Vec3f& from, const osg::Vec3f& to, float offsetXY)
|
||||||
{
|
{
|
||||||
osg::Vec3f dir = to - from;
|
osg::Vec3f dir = to - from;
|
||||||
|
@ -13,17 +13,29 @@ namespace MWWorld
|
|||||||
{
|
{
|
||||||
class CellStore;
|
class CellStore;
|
||||||
class ConstPtr;
|
class ConstPtr;
|
||||||
|
class Ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
class PathgridGraph;
|
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();
|
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)
|
inline float getZAngleToDir(const osg::Vec3f& dir)
|
||||||
{
|
{
|
||||||
return std::atan2(dir.x(), dir.y());
|
return std::atan2(dir.x(), dir.y());
|
||||||
|
@ -176,12 +176,12 @@ recast scale factor
|
|||||||
|
|
||||||
:Type: floating point
|
:Type: floating point
|
||||||
:Range: > 0.0
|
:Range: > 0.0
|
||||||
:Default: 0.017647058823529415
|
:Default: 0.023529411764705882
|
||||||
|
|
||||||
Scale of nav mesh coordinates to world coordinates. Recastnavigation builds voxels for world geometry.
|
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
|
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:
|
"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.
|
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.
|
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.
|
# 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
|
# 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:
|
# "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)
|
||||||
recast scale factor = 0.017647058823529415
|
recast scale factor = 0.023529411764705882
|
||||||
|
|
||||||
# The z-axis cell size to use for fields. (value > 0.0)
|
# The z-axis cell size to use for fields. (value > 0.0)
|
||||||
# Defines voxel/grid/cell size. So their values have significant
|
# 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)
|
# Maximum number of triangles in each node of mesh AABB tree (value > 0)
|
||||||
triangles per chunk = 256
|
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)
|
# Write recast mesh to file in .obj format for each use to update nav mesh (true, false)
|
||||||
enable write recast mesh to file = false
|
enable write recast mesh to file = false
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user