summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoruntodesu <kirill@untode.su>2025-12-26 18:09:35 +0500
committeruntodesu <kirill@untode.su>2025-12-26 18:09:35 +0500
commitf755a1eeb45262fe3aea64efc3914709d572afcc (patch)
treebb08dff89a7ddd446a4363edabac8f9ee0514234
parenteebc2b776717f18e4a24af39b0209afa8eb7404f (diff)
downloadvoxelius-f755a1eeb45262fe3aea64efc3914709d572afcc.tar.bz2
voxelius-f755a1eeb45262fe3aea64efc3914709d572afcc.zip
Add interpolation to Velocity component; fixes #20
- Also disabled snapping to grid for sideways movement as it was somehow messing with player_move code and was making you slide on voxels as if you were on ice (not good)
-rw-r--r--src/game/client/entity/camera.cc6
-rw-r--r--src/game/client/entity/factory.cc5
-rw-r--r--src/game/client/entity/interpolation.cc13
-rw-r--r--src/game/client/entity/player_move.cc1
-rw-r--r--src/game/shared/entity/collision.cc15
-rw-r--r--src/game/shared/entity/velocity.hh9
6 files changed, 38 insertions, 11 deletions
diff --git a/src/game/client/entity/camera.cc b/src/game/client/entity/camera.cc
index 2009066..27603cf 100644
--- a/src/game/client/entity/camera.cc
+++ b/src/game/client/entity/camera.cc
@@ -8,6 +8,7 @@
#include "core/math/angles.hh"
+#include "shared/entity/grounded.hh"
#include "shared/entity/head.hh"
#include "shared/entity/transform.hh"
#include "shared/entity/velocity.hh"
@@ -87,7 +88,7 @@ void camera::update(void)
const auto& head = globals::dimension->entities.get<client::HeadIntr>(globals::player);
const auto& transform = globals::dimension->entities.get<client::TransformIntr>(globals::player);
- const auto& velocity = globals::dimension->entities.get<Velocity>(globals::player);
+ const auto& velocity = globals::dimension->entities.get<client::VelocityIntr>(globals::player);
camera::angles = transform.angles + head.angles;
camera::position_chunk = transform.chunk;
@@ -98,8 +99,7 @@ void camera::update(void)
auto client_angles = camera::angles;
- if(!toggles::get(TOGGLE_PM_FLIGHT)) {
- // Apply the quake-like view rolling
+ if(!toggles::get(TOGGLE_PM_FLIGHT) && globals::dimension->entities.try_get<Grounded>(globals::player)) {
client_angles[2] = math::radians(-camera::roll_angle.get_value() * glm::dot(velocity.value / PMOVE_MAX_SPEED_GROUND, right_vector));
}
diff --git a/src/game/client/entity/factory.cc b/src/game/client/entity/factory.cc
index f4724c5..94a9698 100644
--- a/src/game/client/entity/factory.cc
+++ b/src/game/client/entity/factory.cc
@@ -5,6 +5,7 @@
#include "shared/entity/factory.hh"
#include "shared/entity/head.hh"
#include "shared/entity/transform.hh"
+#include "shared/entity/velocity.hh"
#include "shared/world/dimension.hh"
@@ -24,6 +25,10 @@ void client::create_player(Dimension* dimension, entt::entity entity)
dimension->entities.emplace_or_replace<client::TransformIntr>(entity, transform);
dimension->entities.emplace_or_replace<client::TransformPrev>(entity, transform);
+ const auto& velocity = dimension->entities.get<Velocity>(entity);
+ dimension->entities.emplace_or_replace<client::VelocityIntr>(entity, velocity);
+ dimension->entities.emplace_or_replace<client::VelocityPrev>(entity, velocity);
+
if(globals::sound_ctx) {
dimension->entities.emplace_or_replace<SoundEmitter>(entity);
}
diff --git a/src/game/client/entity/interpolation.cc b/src/game/client/entity/interpolation.cc
index 69fd487..86af971 100644
--- a/src/game/client/entity/interpolation.cc
+++ b/src/game/client/entity/interpolation.cc
@@ -6,6 +6,7 @@
#include "shared/entity/head.hh"
#include "shared/entity/transform.hh"
+#include "shared/entity/velocity.hh"
#include "shared/world/dimension.hh"
@@ -53,11 +54,23 @@ static void head_interpolate(float alpha)
}
}
+static void velocity_interpolate(float alpha)
+{
+ auto group = globals::dimension->entities.group<client::VelocityIntr>(entt::get<Velocity, client::VelocityPrev>);
+
+ for(auto [entity, interp, current, previous] : group.each()) {
+ interp.value[0] = glm::mix(previous.value[0], current.value[0], alpha);
+ interp.value[1] = glm::mix(previous.value[1], current.value[1], alpha);
+ interp.value[2] = glm::mix(previous.value[2], current.value[2], alpha);
+ }
+}
+
void interpolation::update(void)
{
if(globals::dimension) {
auto alpha = static_cast<float>(globals::fixed_accumulator) / static_cast<float>(globals::fixed_frametime_us);
transform_interpolate(alpha);
head_interpolate(alpha);
+ velocity_interpolate(alpha);
}
} \ No newline at end of file
diff --git a/src/game/client/entity/player_move.cc b/src/game/client/entity/player_move.cc
index 14d64cc..edf9150 100644
--- a/src/game/client/entity/player_move.cc
+++ b/src/game/client/entity/player_move.cc
@@ -161,6 +161,7 @@ void player_move::fixed_update(void)
// Interpolation - preserve current component states
globals::dimension->entities.emplace_or_replace<client::TransformPrev>(globals::player, transform);
+ globals::dimension->entities.emplace_or_replace<client::VelocityPrev>(globals::player, velocity);
glm::fvec3 forward, right;
math::vectors(glm::fvec3(0.0f, head.angles[1], 0.0f), &forward, &right, nullptr);
diff --git a/src/game/shared/entity/collision.cc b/src/game/shared/entity/collision.cc
index 1be1ded..8da6405 100644
--- a/src/game/shared/entity/collision.cc
+++ b/src/game/shared/entity/collision.cc
@@ -16,7 +16,7 @@
#include "shared/globals.hh"
static int vgrid_collide(const Dimension* dimension, int d, Collision& collision, Transform& transform, Velocity& velocity,
- VoxelMaterial& touch_surface)
+ VoxelMaterial& touch_surface, bool enable_snapping_to_grid)
{
auto movespeed = globals::fixed_frametime * velocity.value[d];
auto movesign = math::sign<int>(movespeed);
@@ -135,15 +135,15 @@ static int vgrid_collide(const Dimension* dimension, int d, Collision& collision
snap_to_closest_vbox = true;
}
- if(snap_to_closest_vbox) {
+ if(snap_to_closest_vbox && enable_snapping_to_grid) {
auto vbox_center = 0.5f * closest_vbox.min[d] + 0.5f * closest_vbox.max[d];
auto vbox_halfsize = 0.5f * closest_vbox.max[d] - 0.5f * closest_vbox.min[d];
if(movesign < 0) {
- transform.local[d] = vbox_center + vbox_halfsize + ref_halfsize[d] - ref_center[d] + 0.01f;
+ transform.local[d] = vbox_center + vbox_halfsize + ref_halfsize[d] - ref_center[d] + 0.01f * globals::fixed_frametime;
}
else {
- transform.local[d] = vbox_center - vbox_halfsize - ref_halfsize[d] - ref_center[d] - 0.01f;
+ transform.local[d] = vbox_center - vbox_halfsize - ref_halfsize[d] - ref_center[d] - 0.01f * globals::fixed_frametime;
}
}
@@ -162,10 +162,11 @@ void Collision::fixed_update(Dimension* dimension)
for(auto [entity, collision, transform, velocity] : group.each()) {
auto surface = VMAT_UNKNOWN;
- auto vertical_move = vgrid_collide(dimension, 1, collision, transform, velocity, surface);
+ auto vertical_move = vgrid_collide(dimension, 1, collision, transform, velocity, surface, true);
if(dimension->entities.any_of<Gravity>(entity)) {
if(vertical_move == math::sign<int>(dimension->get_gravity())) {
+ spdlog::info("grounded");
dimension->entities.emplace_or_replace<Grounded>(entity, Grounded { surface });
}
else {
@@ -179,7 +180,7 @@ void Collision::fixed_update(Dimension* dimension)
dimension->entities.remove<Grounded>(entity);
}
- vgrid_collide(dimension, 0, collision, transform, velocity, surface);
- vgrid_collide(dimension, 2, collision, transform, velocity, surface);
+ vgrid_collide(dimension, 0, collision, transform, velocity, surface, false);
+ vgrid_collide(dimension, 2, collision, transform, velocity, surface, false);
}
}
diff --git a/src/game/shared/entity/velocity.hh b/src/game/shared/entity/velocity.hh
index 69fce9e..0266bd0 100644
--- a/src/game/shared/entity/velocity.hh
+++ b/src/game/shared/entity/velocity.hh
@@ -2,7 +2,7 @@
class Dimension;
-struct Velocity final {
+struct Velocity {
glm::fvec3 value;
public:
@@ -11,3 +11,10 @@ public:
// NOTE: This system was previously called inertial
static void fixed_update(Dimension* dimension);
};
+
+namespace client
+{
+// Client-side only - interpolated and previous velocity
+struct VelocityIntr final : public Velocity {};
+struct VelocityPrev final : public Velocity {};
+} // namespace client