Smooth player movement and viewbobbing
This commit is contained in:
parent
88c04c1823
commit
c941ed9525
@ -8,7 +8,8 @@ game::Player::Player(World* world, size_t sector_idx, const glm::vec3& position)
|
|||||||
pitch_(0.0f),
|
pitch_(0.0f),
|
||||||
input_(0),
|
input_(0),
|
||||||
cam_forward_(0.0f),
|
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_);
|
float pitch_sin = glm::sin(pitch_);
|
||||||
|
|
||||||
// MOVEMENT
|
// MOVEMENT
|
||||||
glm::vec2 velocity_xy(0.0f);
|
glm::vec2 desire_xy(0.0f);
|
||||||
if (input_ & PI_FORWARD)
|
if (input_ & PI_FORWARD)
|
||||||
velocity_xy.y += 1.0f;
|
desire_xy.y += 1.0f;
|
||||||
|
|
||||||
if (input_ & PI_BACKWARD)
|
if (input_ & PI_BACKWARD)
|
||||||
velocity_xy.y -= 1.0f;
|
desire_xy.y -= 1.0f;
|
||||||
|
|
||||||
if (input_ & PI_LEFT)
|
if (input_ & PI_LEFT)
|
||||||
velocity_xy.x -= 1.0f;
|
desire_xy.x -= 1.0f;
|
||||||
|
|
||||||
if (input_ & PI_RIGHT)
|
if (input_ & PI_RIGHT)
|
||||||
velocity_xy.x += 1.0f;
|
desire_xy.x += 1.0f;
|
||||||
|
|
||||||
glm::mat2 movement_basis(
|
glm::mat2 movement_basis(
|
||||||
yaw_cos, -yaw_sin,
|
yaw_cos, -yaw_sin,
|
||||||
yaw_sin, yaw_cos
|
yaw_sin, yaw_cos
|
||||||
);
|
);
|
||||||
|
|
||||||
float speed = 3.0f; // Base speed
|
if (glm::length(desire_xy) > 0.01f)
|
||||||
|
|
||||||
glm::vec2 normalized_velocity_xy(0.0f);
|
|
||||||
if (glm::length(velocity_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(
|
glm::vec3 velocity = glm::vec3(
|
||||||
normalized_velocity_xy * speed,
|
velocity_xy,
|
||||||
-1.0f // No vertical movement for now
|
-1.0f // No vertical movement for now
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -75,14 +101,52 @@ void game::Player::Update(float dt)
|
|||||||
const glm::mat3& occu_basis = occu_->GetBasis();
|
const glm::mat3& occu_basis = occu_->GetBasis();
|
||||||
cam_forward_ = occu_basis * glm::vec3(yaw_sin * pitch_cos, yaw_cos * pitch_cos, pitch_sin);
|
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_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
|
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();
|
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_;
|
forward = cam_forward_;
|
||||||
up = cam_up_;
|
up = cam_up_;
|
||||||
}
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@ -14,8 +14,16 @@ namespace game
|
|||||||
|
|
||||||
// in occu's sector space
|
// in occu's sector space
|
||||||
glm::vec3 cam_forward_;
|
glm::vec3 cam_forward_;
|
||||||
|
glm::vec3 cam_right_;
|
||||||
glm::vec3 cam_up_;
|
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:
|
public:
|
||||||
Player(World* world, size_t sector_idx, const glm::vec3& position);
|
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;
|
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);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user