From 411bfecedff23deae29a63936b06768329fd89b1 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 19 Feb 2026 23:47:25 +0300 Subject: [PATCH] update PhysicsSolver.cpp --- src/physics/PhysicsSolver.cpp | 63 +++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 11 deletions(-) diff --git a/src/physics/PhysicsSolver.cpp b/src/physics/PhysicsSolver.cpp index 7ba00e61a..99ca01e40 100644 --- a/src/physics/PhysicsSolver.cpp +++ b/src/physics/PhysicsSolver.cpp @@ -40,13 +40,14 @@ void PhysicsSolver::step( float py = pos.y; float pz = pos.z; - vel += gravity * dt * gravityScale; if (hitbox.type == BodyType::DYNAMIC) { colisionCalc(chunks, hitbox, vel, pos, half, (prevGrounded && gravityScale > 0.0f) ? hitbox.stepHeight : 0.0f); } + vel += gravity * dt * gravityScale; pos += vel * dt + gravity * gravityScale * dt * dt * 0.5f; + if (hitbox.grounded && pos.y < py) { pos.y = py; } @@ -58,7 +59,7 @@ void PhysicsSolver::step( hitbox.grounded = false; aabb = AABB(pos - half, pos + half); - aabb.scale(glm::vec3(1.0f - E * 2, 1.0f, 1.0f - E * 2)); + aabb.scale(glm::vec3(1.0f - E * 4, 1.0f, 1.0f - E * 4)); for (int ix = 0; ix <= glm::ceil((half.x-E)*2); ix++) { float x = (px-half.x+E) + ix; for (int iz = 0; iz <= glm::ceil((half.z-E)*2); iz++){ @@ -76,7 +77,7 @@ void PhysicsSolver::step( hitbox.grounded = false; aabb = AABB(pos - half, pos + half); - aabb.scale(glm::vec3(1.0f - E * 2, 1.0f, 1.0f - E * 2)); + aabb.scale(glm::vec3(1.0f - E * 4, 1.0f, 1.0f - E * 4)); for (int ix = 0; ix <= glm::ceil((half.x-E)*2); ix++) { float x = (pos.x-half.x+E) + ix; for (int iz = 0; iz <= glm::ceil((half.z-E)*2); iz++){ @@ -158,13 +159,12 @@ static bool calc_collision_neg( glm::vec3& pos, glm::vec3& vel, const glm::vec3& half, - float stepHeight, - float margin = 1.0f + float stepHeight ) { if (vel[nx] >= 0.0f) { return false; } - glm::vec3 offset(0.0f, (stepHeight + E) * margin, 0.0f); + glm::vec3 offset(0.0f, stepHeight + E, 0.0f); for (int iy = 0; iy <= glm::ceil(((half-offset*0.5f)[ny]-E)*2); iy++) { glm::vec3 coord; coord[ny] = ((pos+offset)[ny]-half[ny]+E) + iy; @@ -177,11 +177,12 @@ static bool calc_collision_neg( scale[nz] = 1.0f - E * 2.0f; boxAABB.scale(scale); boxAABB = boxAABB + offset; + boxAABB.b.y -= stepHeight; if (const auto aabb = chunks.isObstacleAt(coord.x, coord.y, coord.z, boxAABB)) { vel[nx] = 0.0f; - float newx = std::floor(coord[nx]) + half[nx] + aabb->max()[nx] + E * margin; - if (newx - pos[nx] <= E * margin) { + float newx = std::floor(coord[nx]) + half[nx] + aabb->max()[nx] + E; + if (newx - pos[nx] <= E) { pos[nx] = newx; } return true; @@ -191,6 +192,41 @@ static bool calc_collision_neg( return false; } +static bool calc_collision_neg_y( + const GlobalChunks& chunks, + glm::vec3& pos, + glm::vec3& vel, + const glm::vec3& half +) { + if (vel.y >= 0.0f) { + return false; + } + for (int ix = 0; ix <= glm::ceil((half.x-E)*2); ix++) { + glm::vec3 coord; + coord.x = (pos.x-half.x+E) + ix; + for (int iz = 0; iz <= glm::ceil((half.z-E)*2); iz++){ + coord.z = (pos.z-half.z+E) + iz; + coord.y = (pos.y-half.y-E); + + auto boxAABB = AABB(pos - half, pos + half); + glm::vec3 scale(1.0f); + scale.x = 1.0f - E * 4.0f; + scale.z = 1.0f - E * 4.0f; + boxAABB.scale(scale); + + if (const auto aabb = chunks.isObstacleAt(coord.x, coord.y, coord.z, boxAABB)) { + vel.y = 0.0f; + float newx = std::floor(coord.y) + half.y + aabb->max().y; + if (newx - pos.y <= E) { + pos.y = newx; + } + return true; + } + } + } + return false; +} + template static void calc_collision_pos( const GlobalChunks& chunks, @@ -215,6 +251,7 @@ static void calc_collision_pos( scale[nz] = 1.0f - E * 2.0f; boxAABB.scale(scale); boxAABB = boxAABB + offset; + boxAABB.b.y -= stepHeight; if (const auto aabb = chunks.isObstacleAt(coord.x, coord.y, coord.z, boxAABB)) { vel[nx] = 0.0f; @@ -246,13 +283,13 @@ void PhysicsSolver::colisionCalc( calc_collision_neg<2, 1, 0>(chunks, pos, vel, half, stepHeight); calc_collision_pos<2, 1, 0>(chunks, pos, vel, half, stepHeight); - if (calc_collision_neg<1, 0, 2>(chunks, pos, vel, half, 0.0f, 0.0f)) { + if (calc_collision_neg_y(chunks, pos, vel, half)) { hitbox.grounded = true; } if (stepHeight > 0.0 && vel.y <= 0.0f){ AABB boxAABB = AABB(-half, +half); - boxAABB.scale(glm::vec3(1.0f - E, 1.0f, 1.0f - E)); + boxAABB.scale(glm::vec3(1.0f - E * 2, 1.0f, 1.0f - E * 2)); boxAABB = boxAABB.translated(pos); for (int ix = 0; ix <= glm::ceil((half.x-E)*2); ix++) { @@ -272,12 +309,16 @@ void PhysicsSolver::colisionCalc( } } if (vel.y > 0.0f){ + AABB boxAABB = AABB(-half, +half); + boxAABB.scale(glm::vec3(1.0f - E* 2, 1.0f, 1.0f - E * 2)); + boxAABB = boxAABB.translated(pos); + for (int ix = 0; ix <= glm::ceil((half.x-E)*2); ix++) { float x = (pos.x-half.x+E) + ix; for (int iz = 0; iz <= glm::ceil((half.z-E)*2); iz++) { float z = (pos.z-half.z+E) + iz; float y = (pos.y+half.y+E); - if ((aabb = chunks.isObstacleAt(x,y,z, AABB(pos - half, pos + half)))){ + if ((aabb = chunks.isObstacleAt(x,y,z, boxAABB))){ vel.y = 0.0f; float newy = std::floor(y) - half.y + aabb->min().y - E; if (std::abs(newy-pos.y) <= MAX_FIX) {