From c941ed95253f8630facb7691797eead9ad5b610a Mon Sep 17 00:00:00 2001 From: tovjemam Date: Wed, 13 Aug 2025 16:56:02 +0200 Subject: [PATCH] Smooth player movement and viewbobbing --- src/game/player.cpp | 92 ++++++++++++++++++++++++++++++++++++++------- src/game/player.hpp | 10 +++++ 2 files changed, 88 insertions(+), 14 deletions(-) diff --git a/src/game/player.cpp b/src/game/player.cpp index cc50bb6..1d90a56 100644 --- a/src/game/player.cpp +++ b/src/game/player.cpp @@ -8,7 +8,8 @@ game::Player::Player(World* world, size_t sector_idx, const glm::vec3& position) pitch_(0.0f), input_(0), cam_forward_(0.0f), - cam_up_(0.0f) + cam_up_(0.0f), + cam_right_(0.0f) { } @@ -35,34 +36,59 @@ void game::Player::Update(float dt) float pitch_sin = glm::sin(pitch_); // MOVEMENT - glm::vec2 velocity_xy(0.0f); + glm::vec2 desire_xy(0.0f); if (input_ & PI_FORWARD) - velocity_xy.y += 1.0f; + desire_xy.y += 1.0f; if (input_ & PI_BACKWARD) - velocity_xy.y -= 1.0f; + desire_xy.y -= 1.0f; if (input_ & PI_LEFT) - velocity_xy.x -= 1.0f; + desire_xy.x -= 1.0f; if (input_ & PI_RIGHT) - velocity_xy.x += 1.0f; + desire_xy.x += 1.0f; glm::mat2 movement_basis( yaw_cos, -yaw_sin, yaw_sin, yaw_cos ); - float speed = 3.0f; // Base speed - - glm::vec2 normalized_velocity_xy(0.0f); - if (glm::length(velocity_xy) > 0.01f) + if (glm::length(desire_xy) > 0.01f) { - normalized_velocity_xy = glm::normalize(movement_basis * velocity_xy); + desire_xy = glm::normalize(movement_basis * desire_xy); + } + else + { + desire_xy = glm::vec2(0.0f); } + glm::vec2 target_xy = desire_xy * max_speed_; + + glm::vec2 velocity_xy = glm::vec2(velocity_.x, velocity_.y); + glm::vec2 difference_xy = target_xy - velocity_xy; + float dist = glm::length(difference_xy); + + if (dist > 0.001f) + { + float accel = acceleration_; + + if (glm::length(velocity_xy) > glm::length(target_xy)) + { + // If we are moving faster than the target, apply deceleration + accel = deceleration_; + } + + float delta = dt * accel; + float t = glm::clamp(delta / dist, 0.0f, 1.0f); + + velocity_xy = glm::mix(velocity_xy, target_xy, t); + } + + current_speed_ = glm::length(velocity_xy); + glm::vec3 velocity = glm::vec3( - normalized_velocity_xy * speed, + velocity_xy, -1.0f // No vertical movement for now ); @@ -75,14 +101,52 @@ void game::Player::Update(float dt) const glm::mat3& occu_basis = occu_->GetBasis(); cam_forward_ = occu_basis * glm::vec3(yaw_sin * pitch_cos, yaw_cos * pitch_cos, pitch_sin); cam_up_ = occu_basis[2]; // Up vector is always the Z axis in sector space + cam_right_ = glm::cross(cam_forward_, cam_up_); } + + time_ += dt; } void game::Player::GetPOV(size_t& sector_idx, glm::vec3& position, glm::vec3& forward, glm::vec3& up) const { + float scale = 1.0f; + sector_idx = occu_->GetSector().GetIndex(); - position = occu_->GetPosition() + cam_up_ * 0.7f; + + glm::vec2 bobbing_offset = GetBobbingOffset(time_, 0.01f * current_speed_); + glm::vec3 offset = ((cam_up_ * (0.7f + bobbing_offset.y)) + cam_right_ * bobbing_offset.x) * scale; + + position = occu_->GetPosition() + offset; forward = cam_forward_; up = cam_up_; -} \ No newline at end of file + + if (touching_portal_ && touching_portal_->link) + { + float sd = glm::dot(glm::vec3(touching_portal_->plane), position) + touching_portal_->plane.w; + + // Position is behind portal, render from other sector + if (sd < 0.0f) + { + sector_idx = touching_portal_->link->sector->GetIndex(); + position = touching_portal_->tr_position * glm::vec4(position, 1.0f); + forward = touching_portal_->tr_basis * forward; + up = touching_portal_->tr_basis * up; + + } + } +} + +glm::vec2 game::Player::GetBobbingOffset(float t, float amplitude) +{ + // Frequency and amplitude can be adjusted to tweak the effect + float frequency = 10.0f;// 2f * MathHelper.TwoPi; // One full cycle per t=1 + float xAmplitude = amplitude; + float yAmplitude = 0.25f * amplitude; + + glm::vec2 offset; + offset.x = glm::sin(t * frequency) * xAmplitude; + offset.y = glm::sin(t * frequency * 2.0f) * yAmplitude; + + return offset; +} diff --git a/src/game/player.hpp b/src/game/player.hpp index 40e08a4..4dea2eb 100644 --- a/src/game/player.hpp +++ b/src/game/player.hpp @@ -14,8 +14,16 @@ namespace game // in occu's sector space glm::vec3 cam_forward_; + glm::vec3 cam_right_; glm::vec3 cam_up_; + float max_speed_ = 4.0f; + float acceleration_ = 50.0f; + float deceleration_ = 20.0f; + + float time_ = 0.0f; + float current_speed_ = 0.0f; + public: Player(World* world, size_t sector_idx, const glm::vec3& position); @@ -28,6 +36,8 @@ namespace game void GetPOV(size_t& sector_idx, glm::vec3& position, glm::vec3& forward, glm::vec3& up) const; + private: + static glm::vec2 GetBobbingOffset(float t, float amplitude); };