Skip to content

Commit d58b94e

Browse files
authored
Merge pull request #253 from Architector4/patch-const-time-human-tilt
AHuman - make some body movements delta time independent
2 parents 8d27184 + b669f0d commit d58b94e

File tree

2 files changed

+39
-7
lines changed

2 files changed

+39
-7
lines changed

Source/Entities/AHuman.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "AHuman.h"
22

33
#include "AtomGroup.h"
4+
#include "RTETools.h"
45
#include "ThrownDevice.h"
56
#include "Arm.h"
67
#include "Leg.h"
@@ -2563,8 +2564,8 @@ void AHuman::Update() {
25632564
if (m_ProneState == GOPRONE) {
25642565
if (!m_ProneTimer.IsPastSimMS(333)) {
25652566
if (std::abs(rotDiff) > 0.1F && std::abs(rotDiff) < c_PI) {
2566-
m_AngularVel += rotDiff * 0.4F;
2567-
m_Vel.m_X += (m_HFlipped ? -std::abs(rotDiff) : std::abs(rotDiff)) / std::max(m_Vel.GetMagnitude(), 4.0F);
2567+
m_AngularVel += rotDiff * 24.0F * g_TimerMan.GetDeltaTimeSecs();
2568+
m_Vel.m_X += (m_HFlipped ? -std::abs(rotDiff) : std::abs(rotDiff)) / std::max(m_Vel.GetMagnitude(), 4.0F) * 60.0F * g_TimerMan.GetDeltaTimeSecs();
25682569
}
25692570
} else {
25702571
// Done going down, now stay down without spring.
@@ -2574,9 +2575,9 @@ void AHuman::Update() {
25742575
} else if (m_ProneState == LAYINGPRONE) {
25752576
// If down, try to keep flat against the ground.
25762577
if (std::abs(rotDiff) > c_SixteenthPI && std::abs(rotDiff) < c_HalfPI) {
2577-
m_AngularVel += rotDiff * 0.65F;
2578+
m_AngularVel += rotDiff * 39.0F * g_TimerMan.GetDeltaTimeSecs();
25782579
} else if (std::abs(m_AngularVel) > 0.3F) {
2579-
m_AngularVel *= 0.85F;
2580+
m_AngularVel = ExpDecay(m_AngularVel, 0, 10, g_TimerMan.GetDeltaTimeSecs());
25802581
}
25812582
}
25822583
} else {
@@ -2596,6 +2597,7 @@ void AHuman::Update() {
25962597
rot = rotTarget;
25972598
} else {
25982599
// Lerp towards the angle
2600+
// TODO: make framerate independent
25992601
m_AngularVel = m_AngularVel * (0.98F - 0.06F * (m_Health / m_MaxHealth)) - (rotDiff * 0.5F);
26002602
}
26012603

@@ -2612,14 +2614,14 @@ void AHuman::Update() {
26122614

26132615
float rotDiff = rotTarget - rot;
26142616
if (std::abs(rotDiff) > 0.1F && std::abs(rotDiff) < c_PI) {
2615-
m_AngularVel += rotDiff * 0.05F;
2617+
m_AngularVel += rotDiff * 3.0F * g_TimerMan.GetDeltaTimeSecs();
26162618
}
26172619
} else if (m_Status == DYING) {
26182620
float rotTarget = m_Vel.m_X - (rot + m_AngularVel) > 0 ? -c_HalfPI : c_HalfPI;
26192621
float rotDiff = rotTarget - rot;
26202622
if (!m_DeathTmr.IsPastSimMS(125) && std::abs(rotDiff) > 0.1F && std::abs(rotDiff) < c_PI) {
26212623
// TODO: finetune this for situations like low gravity!
2622-
float velScalar = 0.5F; //* (g_SceneMan.GetGlobalAcc().GetY() * m_GlobalAccScalar) / c_PPM;
2624+
float velScalar = 30.0F * g_TimerMan.GetDeltaTimeSecs(); //* (g_SceneMan.GetGlobalAcc().GetY() * m_GlobalAccScalar) / c_PPM;
26232625
m_AngularVel += rotDiff * velScalar;
26242626
m_Vel.m_X += (rotTarget > 0 ? -std::abs(rotDiff) : std::abs(rotDiff)) * velScalar * 0.5F;
26252627
} else {
@@ -2634,7 +2636,7 @@ void AHuman::Update() {
26342636
if (!m_pHead && m_Status != DYING && m_Status != DEAD) {
26352637
m_Health -= m_MaxHealth + 1.0F;
26362638
} else if (!m_pFGArm && !m_pBGArm && !m_pFGLeg && !m_pBGLeg && m_Status != DYING && m_Status != DEAD) {
2637-
m_Health -= 0.1F;
2639+
m_Health -= 6.0F * g_TimerMan.GetDeltaTimeSecs();
26382640
}
26392641

26402642
if (m_Status == DYING) {

Source/System/RTETools.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,5 +301,35 @@ namespace RTE {
301301
template <typename Type> int Sign(const Type& value) {
302302
return (Type(0) < value) - (Type(0) > value);
303303
}
304+
305+
/// Exponential decay function. Allows decaying a value from A to B at the same rate regardless of delta time. Always stable.
306+
///
307+
/// As an example, assuming variables like this:
308+
/// float current = 1.0f;
309+
/// float target = 0.0f;
310+
/// float decay = 10.0f;
311+
///
312+
/// Then running this:
313+
///
314+
/// current = ExpDecay(current, target, decay, 1.0f / 30.0f);
315+
///
316+
/// Preduces the same result (barring precision errors) as:
317+
///
318+
/// current = ExpDecay(current, target, decay, 1.0f / 60.0f);
319+
/// current = ExpDecay(current, target, decay, 1.0f / 60.0f);
320+
///
321+
/// In both cases, "current" will be equal to about 0.716531310573789.
322+
///
323+
/// Lecture on the topic: https://youtube.com/watch?v=LSNQuFEDOyQ
324+
///
325+
/// @param current The current value that we're decaying.
326+
/// @param target Target we're decaying to.
327+
/// @param decay Rate of decay. For example, with 0.7 the value will be decayed about halfway there in 1 second.
328+
/// @param deltaTime Amount of time of decay to simulate.
329+
/// @returns The decayed value.
330+
inline float ExpDecay(float current, float target, float decay, float deltaTime) {
331+
return target + (current - target) * std::exp(-decay * deltaTime);
332+
}
333+
304334
#pragma endregion
305335
} // namespace RTE

0 commit comments

Comments
 (0)