smoothing test

This commit is contained in:
2024-01-27 16:40:38 +01:00
parent 6450354d0f
commit a71a5ea2bc
4 changed files with 109 additions and 28 deletions

View File

@@ -0,0 +1,18 @@
#pragma once
namespace blitz {
struct EMASmoother {
private:
float Alpha;
public:
float Current;
EMASmoother::EMASmoother();
void TickUnitT(float target);
void Tick(float target, float delta);
float GetAlpha();
void SetAlpha(float alpha);
void SetSmoothingTime(float t);
};
}

View File

@@ -1,4 +1,5 @@
#pragma once
#include "blitz/common/Smoothing.h"
namespace blitz {
namespace game {
@@ -11,7 +12,17 @@ namespace input {
class PlayerController {
private:
game::Player* m_Player;
game::Player* m_Player;
EMASmoother m_DxSmoother;
/// maximum x-axis velocity
float m_MaxDx;
/// current (target) x-axis velocity
float m_Dx;
EMASmoother m_DySmoother;
/// maximum (target) y-axis velocity
float m_MaxDy;
/// current (target) y-axis velocity
float m_Dy;
/// current z-axis velocity
float m_Dz;
/// maximum z-axis velocity (velocity at initial keypress)

View File

@@ -0,0 +1,36 @@
#include <cmath>>
#include <cassert>
namespace blitz {
struct EMASmoother {
private:
float Alpha;
public:
float Current;
EMASmoother::EMASmoother() : Alpha(1.0f), Current(0.0f) {}
void TickUnitT(float target) {
Current += Alpha * (target - Current);
}
void Tick(float target, float delta) {
Current += std::powf(Alpha, delta) * (target - Current);
}
float GetAlpha() {
return Alpha;
}
void SetAlpha(float alpha) {
assert(0.0f < alpha && alpha <= 1.0f);
Alpha = alpha;
}
void SetSmoothingTime(float t) {
Alpha = 0.999f;
}
};
}

View File

@@ -10,11 +10,28 @@
namespace blitz {
namespace input {
static constexpr float DEFAULT_JUMP_VEL = 7.5f;
static constexpr float DEFAULT_GRAVITY = 20.0f;
static constexpr float DEFAULT_JUMP_VEL = 7.5;
static constexpr float DEFAULT_GRAVITY = 20.0;
static constexpr float DEFAULT_MAX_LR_SPEED = 10.;
static constexpr float DEFAULT_MAX_FB_SPEED = 10.;
static constexpr float DEFAULT_LR_TOP_SPEED_REACH_TIME = 0.1;
static constexpr float DEFAULT_FB_TOP_SPEED_REACH_TIME = 0.1;
PlayerController::PlayerController() :
m_Player(nullptr), m_MaxDz(DEFAULT_JUMP_VEL), m_Dz(0.0), m_G(DEFAULT_GRAVITY), m_OnGround(true) {
m_Player(nullptr),
m_Dx(0.0),
m_Dy(0.0),
m_MaxDx(DEFAULT_MAX_LR_SPEED),
m_MaxDy(DEFAULT_MAX_FB_SPEED),
m_MaxDz(DEFAULT_JUMP_VEL),
m_Dz(0.0),
m_G(DEFAULT_GRAVITY),
m_OnGround(true)
{
m_DxSmoother.Current = 0.0f;
m_DySmoother.Current = 0.0f;
m_DxSmoother.SetSmoothingTime(DEFAULT_LR_TOP_SPEED_REACH_TIME);
m_DySmoother.SetSmoothingTime(DEFAULT_FB_TOP_SPEED_REACH_TIME);
InputManager::BindMouseMoveCallback(
std::bind(&PlayerController::MouseMotionEvent, this, std::placeholders::_1, std::placeholders::_2));
}
@@ -34,21 +51,12 @@ void PlayerController::Update(float delta) {
if (!m_Player)
return;
static float SpeedFactor = 10.0f;
float Speed = SpeedFactor * delta;
if (InputManager::MouseGrabbed()) {
if (ImGui::IsKeyDown(ImGuiKey_Z)) {
m_Player->AddPosition({std::cos(m_Player->GetYaw()) * Speed, 0, std::sin(m_Player->GetYaw()) * Speed});
} else if (ImGui::IsKeyDown(ImGuiKey_S)) {
m_Player->AddPosition({-std::cos(m_Player->GetYaw()) * Speed, 0, -std::sin(m_Player->GetYaw()) * Speed});
}
float lr = static_cast<float>(ImGui::IsKeyDown(ImGuiKey_W)) - static_cast<float>(ImGui::IsKeyDown(ImGuiKey_S));
float fb = static_cast<float>(ImGui::IsKeyDown(ImGuiKey_Z)) - static_cast<float>(ImGui::IsKeyDown(ImGuiKey_S));
if (ImGui::IsKeyDown(ImGuiKey_Q)) {
m_Player->AddPosition({std::sin(m_Player->GetYaw()) * Speed, 0, -std::cos(m_Player->GetYaw()) * Speed});
} else if (ImGui::IsKeyDown(ImGuiKey_D)) {
m_Player->AddPosition({-std::sin(m_Player->GetYaw()) * Speed, 0, std::cos(m_Player->GetYaw()) * Speed});
}
m_Dx = lr * m_MaxDx;
m_Dy = fb * m_MaxDy;
if (ImGui::IsKeyDown(ImGuiKey::ImGuiKey_Space) && m_OnGround) {
m_Dz = m_MaxDz;
@@ -58,24 +66,32 @@ void PlayerController::Update(float delta) {
UpdatePosition(delta);
}
void PlayerController::UpdatePosition(float delta) {
float dy = m_Dz * delta;
void PlayerController::UpdatePosition(const float delta) {
float yaw = m_Player->GetYaw();
float sine = std::sin(yaw);
float cosine = std::cos(yaw);
m_DxSmoother.Tick(m_Dx, delta);
m_DySmoother.Tick(m_Dy, delta);
float dx = m_Dx * cosine + m_Dy * sine;
float dy = m_Dx * sine - m_Dy * cosine;
float dz = m_Dz * delta;
// the floor here is y-level zero, once downwards collision lands it will be dynmicallly calculated
// assumed to be a negative number
float floor_dist = 0.0f - m_Player->GetPosition().y;
const float floor_dist = 0.0f - m_Player->GetPosition().y;
bool on_ground = dy <= floor_dist;
m_OnGround = on_ground;
if (on_ground) {
dy = floor_dist;
if (m_OnGround = dy <= floor_dist) {
dz = floor_dist;
m_Dz = 0.0f;
} else {
m_Dz -= m_G * delta;
}
m_Player->AddPosition({0, dy, 0});
m_Dz -= m_G * delta;
m_Player->AddPosition({dx, dz, dy});
}
} // namespace input