summaryrefslogtreecommitdiffstats
path: root/src/game/shared/entity
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/shared/entity')
-rw-r--r--src/game/shared/entity/collision.cc31
1 files changed, 21 insertions, 10 deletions
diff --git a/src/game/shared/entity/collision.cc b/src/game/shared/entity/collision.cc
index d9361b1..322bb91 100644
--- a/src/game/shared/entity/collision.cc
+++ b/src/game/shared/entity/collision.cc
@@ -15,6 +15,8 @@
#include "shared/coord.hh"
#include "shared/globals.hh"
+constexpr static float EPSILON = 0.5f;
+
static int vgrid_collide(const Dimension* dimension, int d, Collision& collision, Transform& transform, Velocity& velocity,
VoxelMaterial& touch_surface, bool enable_snapping_to_grid)
{
@@ -87,7 +89,11 @@ static int vgrid_collide(const Dimension* dimension, int d, Collision& collision
auto vbox = voxel->get_collision().push(lpos);
auto vbox_center = 0.5f * vbox.min + 0.5f * vbox.max;
- if(!csg_aabb.intersect(vbox)) {
+ math::AABBf clip_vbox(vbox);
+ clip_vbox.min -= EPSILON * globals::fixed_frametime;
+ clip_vbox.max += EPSILON * globals::fixed_frametime;
+
+ if(!csg_aabb.intersect(clip_vbox)) {
continue; // no intersection
}
@@ -140,10 +146,10 @@ static int vgrid_collide(const Dimension* dimension, int d, Collision& collision
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 * globals::fixed_frametime;
+ transform.local[d] = vbox_center + vbox_halfsize + ref_halfsize[d] - ref_center[d] + EPSILON * globals::fixed_frametime;
}
else {
- transform.local[d] = vbox_center - vbox_halfsize - ref_halfsize[d] - ref_center[d] - 0.01f * globals::fixed_frametime;
+ transform.local[d] = vbox_center - vbox_halfsize - ref_halfsize[d] - ref_center[d] - EPSILON * globals::fixed_frametime;
}
}
@@ -161,12 +167,20 @@ void Collision::fixed_update(Dimension* dimension)
auto group = dimension->entities.group<Collision>(entt::get<Transform, Velocity>);
for(auto [entity, collision, transform, velocity] : group.each()) {
- auto surface = VMAT_UNKNOWN;
- auto vertical_move = vgrid_collide(dimension, 1, collision, transform, velocity, surface, true);
+ auto speedvec = velocity.value;
+ auto hspeed = glm::abs(0.5f * speedvec.x + 0.5f * speedvec.z);
+ auto vspeed = glm::abs(speedvec.y);
+
+ glm::vec<3, VoxelMaterial> surface;
+
+ glm::ivec3 movesign;
+ movesign.x = vgrid_collide(dimension, 0, collision, transform, velocity, surface.x, true);
+ movesign.z = vgrid_collide(dimension, 2, collision, transform, velocity, surface.z, true);
+ movesign.y = vgrid_collide(dimension, 1, collision, transform, velocity, surface.y, true);
if(dimension->entities.any_of<Gravity>(entity)) {
- if(vertical_move == math::sign<int>(dimension->get_gravity())) {
- dimension->entities.emplace_or_replace<Grounded>(entity, Grounded { surface });
+ if(movesign.y == math::sign<int>(dimension->get_gravity())) {
+ dimension->entities.emplace_or_replace<Grounded>(entity, Grounded { surface.y });
}
else {
dimension->entities.remove<Grounded>(entity);
@@ -178,8 +192,5 @@ void Collision::fixed_update(Dimension* dimension)
// concept of resting on the ground (it flies around)
dimension->entities.remove<Grounded>(entity);
}
-
- vgrid_collide(dimension, 0, collision, transform, velocity, surface, false);
- vgrid_collide(dimension, 2, collision, transform, velocity, surface, false);
}
}