From 9fd675895db99fa368e970eeaae38a4502bb9c30 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 13 Jan 2024 21:20:25 +0300 Subject: [PATCH] physics: step height --- src/physics/PhysicsSolver.cpp | 30 ++++++++++++++++++++++++------ src/physics/PhysicsSolver.h | 28 +++++++++++++++++----------- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/physics/PhysicsSolver.cpp b/src/physics/PhysicsSolver.cpp index 2748ffa5..e5a588c9 100644 --- a/src/physics/PhysicsSolver.cpp +++ b/src/physics/PhysicsSolver.cpp @@ -36,7 +36,8 @@ void PhysicsSolver::step( vel += gravity * dt * gravityScale; if (collisions) { - colisionCalc(chunks, hitbox, vel, pos, half); + colisionCalc(chunks, hitbox, vel, pos, half, + (gravityScale > 0.0f) ? 0.5f : 0.0f); } vel.x *= glm::max(0.0f, 1.0f - dt * linear_damping); vel.z *= glm::max(0.0f, 1.0f - dt * linear_damping); @@ -78,7 +79,8 @@ void PhysicsSolver::colisionCalc( Hitbox* hitbox, vec3& vel, vec3& pos, - const vec3 half) + const vec3 half, + float stepHeight) { // step size (smaller - more accurate, but slower) float s = 2.0f/BLOCK_AABB_GRID; @@ -86,7 +88,7 @@ void PhysicsSolver::colisionCalc( const AABB* aabb; if (vel.x < 0.0f){ - for (float y = (pos.y-half.y+E); y <= (pos.y+half.y-E); y+=s){ + for (float y = (pos.y-half.y+E+stepHeight); y <= (pos.y+half.y-E); y+=s){ for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){ float x = (pos.x-half.x-E); if ((aabb = chunks->isObstacleAt(x,y,z))){ @@ -101,7 +103,7 @@ void PhysicsSolver::colisionCalc( } } if (vel.x > 0.0f){ - for (float y = (pos.y-half.y+E); y <= (pos.y+half.y-E); y+=s){ + for (float y = (pos.y-half.y+E+stepHeight); y <= (pos.y+half.y-E); y+=s){ for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){ float x = (pos.x+half.x+E); if ((aabb = chunks->isObstacleAt(x,y,z))){ @@ -117,7 +119,7 @@ void PhysicsSolver::colisionCalc( } if (vel.z < 0.0f){ - for (float y = (pos.y-half.y+E); y <= (pos.y+half.y-E); y+=s){ + for (float y = (pos.y-half.y+E+stepHeight); y <= (pos.y+half.y-E); y+=s){ for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){ float z = (pos.z-half.z-E); if ((aabb = chunks->isObstacleAt(x,y,z))){ @@ -133,7 +135,7 @@ void PhysicsSolver::colisionCalc( } if (vel.z > 0.0f){ - for (float y = (pos.y-half.y+E); y <= (pos.y+half.y-E); y+=s){ + for (float y = (pos.y-half.y+E+stepHeight); y <= (pos.y+half.y-E); y+=s){ for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){ float z = (pos.z+half.z+E); if ((aabb = chunks->isObstacleAt(x,y,z))){ @@ -164,6 +166,22 @@ void PhysicsSolver::colisionCalc( } } } + if (stepHeight > 0.0 && vel.y <= 0.0f){ + for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){ + for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){ + float y = (pos.y-half.y+E); + if ((aabb = chunks->isObstacleAt(x,y,z))){ + vel.y *= 0.0f; + float newy = floor(y) + aabb->max().y + half.y; + if (glm::abs(newy-pos.y) <= MAX_FIX+stepHeight) { + pos.y = newy; + } + hitbox->grounded = true; + break; + } + } + } + } if (vel.y > 0.0f){ for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){ for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){ diff --git a/src/physics/PhysicsSolver.h b/src/physics/PhysicsSolver.h index 6784b417..08bccfca 100644 --- a/src/physics/PhysicsSolver.h +++ b/src/physics/PhysicsSolver.h @@ -8,18 +8,24 @@ class Hitbox; class Chunks; class PhysicsSolver { - glm::vec3 gravity; + glm::vec3 gravity; public: - PhysicsSolver(glm::vec3 gravity); - void step(Chunks* chunks, - Hitbox* hitbox, - float delta, - uint substeps, - bool shifting, - float gravityScale, - bool collisions); - void colisionCalc(Chunks* chunks, Hitbox* hitbox, glm::vec3& vel, glm::vec3& pos, const glm::vec3 half); - bool isBlockInside(int x, int y, int z, Hitbox* hitbox); + PhysicsSolver(glm::vec3 gravity); + void step(Chunks* chunks, + Hitbox* hitbox, + float delta, + uint substeps, + bool shifting, + float gravityScale, + bool collisions); + void colisionCalc( + Chunks* chunks, + Hitbox* hitbox, + glm::vec3& vel, + glm::vec3& pos, + const glm::vec3 half, + float stepHeight); + bool isBlockInside(int x, int y, int z, Hitbox* hitbox); }; #endif /* PHYSICS_PHYSICSSOLVER_H_ */