mirror of https://github.com/OpenMW/openmw.git
Apply uniform random deviation to AI reaction timer
This allows to distribute AI reaction calls over time. Before this change actors appearing at the same frame will react in the same frame over and over because AI reaction period is constant. It creates a non-uniform CPU usage over frames. If a single frame has too many AI reactions it may cause stuttering when there are too many actors on a scene for current system. Another concern is a synchronization of actions between creatures and NPC. They start to go or hit at the same frame that is unnatural.pull/3057/head
parent
d13d90a50d
commit
675c0ab72f
@ -0,0 +1,26 @@
|
||||
#ifndef OPENMW_MECHANICS_AITIMER_H
|
||||
#define OPENMW_MECHANICS_AITIMER_H
|
||||
|
||||
#include <components/misc/rng.hpp>
|
||||
#include <components/misc/timer.hpp>
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
constexpr float AI_REACTION_TIME = 0.25f;
|
||||
|
||||
class AiReactionTimer
|
||||
{
|
||||
public:
|
||||
static constexpr float sDeviation = 0.1f;
|
||||
|
||||
Misc::TimerStatus update(float duration) { return mImpl.update(duration); }
|
||||
|
||||
void reset() { mImpl.reset(Misc::Rng::deviate(0, sDeviation)); }
|
||||
|
||||
private:
|
||||
Misc::DeviatingPeriodicTimer mImpl {AI_REACTION_TIME, sDeviation,
|
||||
Misc::Rng::deviate(0, sDeviation)};
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,42 @@
|
||||
#ifndef OPENMW_COMPONENTS_MISC_TIMER_H
|
||||
#define OPENMW_COMPONENTS_MISC_TIMER_H
|
||||
|
||||
#include "rng.hpp"
|
||||
|
||||
namespace Misc
|
||||
{
|
||||
enum class TimerStatus
|
||||
{
|
||||
Waiting,
|
||||
Elapsed,
|
||||
};
|
||||
|
||||
class DeviatingPeriodicTimer
|
||||
{
|
||||
public:
|
||||
explicit DeviatingPeriodicTimer(float period, float deviation, float timeLeft)
|
||||
: mPeriod(period), mDeviation(deviation), mTimeLeft(timeLeft)
|
||||
{}
|
||||
|
||||
TimerStatus update(float duration)
|
||||
{
|
||||
if (mTimeLeft > 0)
|
||||
{
|
||||
mTimeLeft -= duration;
|
||||
return TimerStatus::Waiting;
|
||||
}
|
||||
|
||||
mTimeLeft = Rng::deviate(mPeriod, mDeviation);
|
||||
return TimerStatus::Elapsed;
|
||||
}
|
||||
|
||||
void reset(float timeLeft) { mTimeLeft = timeLeft; }
|
||||
|
||||
private:
|
||||
const float mPeriod;
|
||||
const float mDeviation;
|
||||
float mTimeLeft;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue