From f684c909326ecb4e367e91924de6d05fe90c8f6b Mon Sep 17 00:00:00 2001 From: elsid Date: Sat, 13 Apr 2019 13:19:35 +0200 Subject: [PATCH] Make angular velocity depending on actor speed To avoid moving in circles for actors with high speed. --- apps/openmw/mwmechanics/aipackage.cpp | 4 ++-- apps/openmw/mwmechanics/steering.cpp | 2 +- apps/openmw/mwmechanics/steering.hpp | 9 ++++++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index 94a502544..598292fc3 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -301,7 +301,7 @@ bool MWMechanics::AiPackage::checkWayIsClearForActor(const osg::Vec3f& startPoin return true; const float actorSpeed = actor.getClass().getSpeed(actor); - const float maxAvoidDist = AI_REACTION_TIME * actorSpeed + actorSpeed / MAX_VEL_ANGULAR_RADIANS * 2; // *2 - for reliability + const float maxAvoidDist = AI_REACTION_TIME * actorSpeed + actorSpeed / getAngularVelocity(actorSpeed) * 2; // *2 - for reliability const float distToTarget = osg::Vec2f(endPoint.x(), endPoint.y()).length(); const float offsetXY = distToTarget > maxAvoidDist*1.5? maxAvoidDist : maxAvoidDist/2; @@ -363,7 +363,7 @@ bool MWMechanics::AiPackage::isReachableRotatingOnTheRun(const MWWorld::Ptr& act // get actor's shortest radius for moving in circle float speed = actor.getClass().getSpeed(actor); speed += speed * 0.1f; // 10% real speed inaccuracy - float radius = speed / MAX_VEL_ANGULAR_RADIANS; + float radius = speed / getAngularVelocity(speed); // get radius direction to the center const float* rot = actor.getRefData().getPosition().rot; diff --git a/apps/openmw/mwmechanics/steering.cpp b/apps/openmw/mwmechanics/steering.cpp index 1ef46e1ae..b08a90220 100644 --- a/apps/openmw/mwmechanics/steering.cpp +++ b/apps/openmw/mwmechanics/steering.cpp @@ -32,7 +32,7 @@ bool smoothTurn(const MWWorld::Ptr& actor, float targetAngleRadians, int axis, f if (absDiff < epsilonRadians) return true; - float limit = MAX_VEL_ANGULAR_RADIANS * MWBase::Environment::get().getFrameDuration(); + float limit = getAngularVelocity(actor.getClass().getSpeed(actor)) * MWBase::Environment::get().getFrameDuration(); if (absDiff > limit) diff = osg::sign(diff) * limit; diff --git a/apps/openmw/mwmechanics/steering.hpp b/apps/openmw/mwmechanics/steering.hpp index 632ab3611..f305a6961 100644 --- a/apps/openmw/mwmechanics/steering.hpp +++ b/apps/openmw/mwmechanics/steering.hpp @@ -3,6 +3,8 @@ #include +#include + namespace MWWorld { class Ptr; @@ -12,7 +14,12 @@ namespace MWMechanics { // Max rotating speed, radian/sec -const float MAX_VEL_ANGULAR_RADIANS(10); +inline float getAngularVelocity(const float actorSpeed) +{ + const float baseAngluarVelocity = 10; + const float baseSpeed = 200; + return baseAngluarVelocity * std::max(actorSpeed / baseSpeed, 1.0f); +} /// configure rotation settings for an actor to reach this target angle (eventually) /// @return have we reached the target angle?