1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-26 18:35:20 +00:00

Do not use infinite area cost

Division by zero causes float value to be infinite. When infinite cost is
multiplied by zero distance the result is NaN. After this pathfinding algorithm
state is broken.
This commit is contained in:
elsid 2021-04-13 23:10:43 +02:00
parent a77e1f1812
commit 3c4a9069ae
No known key found for this signature in database
GPG Key ID: B845CB9FEE18AB40

View File

@ -25,6 +25,14 @@
#include <osg/Quat>
namespace
{
float divOrMax(float dividend, float divisor)
{
return divisor == 0 ? std::numeric_limits<float>::max() * std::numeric_limits<float>::epsilon() : dividend / divisor;
}
}
MWMechanics::AiPackage::AiPackage(AiPackageTypeId typeId, const Options& options) :
mTypeId(typeId),
mOptions(options),
@ -439,15 +447,15 @@ DetourNavigator::AreaCosts MWMechanics::AiPackage::getAreaCosts(const MWWorld::P
const MWWorld::Class& actorClass = actor.getClass();
if (flags & DetourNavigator::Flag_swim)
costs.mWater = costs.mWater / actorClass.getSwimSpeed(actor);
costs.mWater = divOrMax(costs.mWater, actorClass.getSwimSpeed(actor));
if (flags & DetourNavigator::Flag_walk)
{
float walkCost;
if (getTypeId() == AiPackageTypeId::Wander)
walkCost = 1.0 / actorClass.getWalkSpeed(actor);
walkCost = divOrMax(1.0, actorClass.getWalkSpeed(actor));
else
walkCost = 1.0 / actorClass.getRunSpeed(actor);
walkCost = divOrMax(1.0, actorClass.getRunSpeed(actor));
costs.mDoor = costs.mDoor * walkCost;
costs.mPathgrid = costs.mPathgrid * walkCost;
costs.mGround = costs.mGround * walkCost;