diff --git a/src/physics/Hitbox.hpp b/src/physics/Hitbox.hpp index 476e1a4aa..ecf41faa3 100644 --- a/src/physics/Hitbox.hpp +++ b/src/physics/Hitbox.hpp @@ -64,6 +64,8 @@ struct Hitbox { float gravityScale = 1.0f; bool crouching = false; float stepHeight = 0.5f; + float mass = 1.0f; + float elasticity = 0.0f; std::string material; std::string groundMaterial; glm::vec3 groundVelocity {}; diff --git a/src/physics/PhysicsSolver.cpp b/src/physics/PhysicsSolver.cpp index 96a4dfbe0..dfea20b67 100644 --- a/src/physics/PhysicsSolver.cpp +++ b/src/physics/PhysicsSolver.cpp @@ -141,9 +141,18 @@ bool PhysicsSolver::calcCollisionNegY( if (pos.y < newy && glm::abs(pos.y - newy) < boxhalf.y) { pos.y = newy; } + const auto& vA = hitbox.velocity; + const auto& vB = box->velocity; + const auto& mA = hitbox.mass; + const auto& mB = box->mass; + + auto velA = (mA * vA + mB * vB + hitbox.elasticity * mB * (vB - vA)) / (mA + mB); + auto velB = (mA * vA + mB * vB + box->elasticity * mA * (vA - vB)) / (mA + mB); + hitbox.groundVelocity = box->position - box->prevPosition; if (vel.y < hitbox.groundVelocity.y / dt) { - vel.y = hitbox.groundVelocity.y / dt * (1.0f - E); + vel.y = velA.y; + box->velocity.y = velB.y; if (hitbox.groundMaterial.empty() && !box->material.empty()) { hitbox.groundMaterial = box->material; } @@ -171,8 +180,9 @@ bool PhysicsSolver::calcCollisionNegY( if (const auto obstacle = chunks.isObstacleAt(coord.x, coord.y, coord.z, aabb)) { float newy = std::floor(coord.y) + half.y + obstacle->max().y; + if (newy >= pos.y) { - vel.y = 0.0f; + vel.y = -hitbox.elasticity * vel.y; pos.y = newy; } return true;