feat: applying Y velocity

This commit is contained in:
MihailRis 2026-03-13 21:31:20 +03:00
parent 06d03f889c
commit 81858bc7f8
3 changed files with 18 additions and 34 deletions

View file

@ -61,7 +61,6 @@ struct Hitbox {
float friction = 1.0f; float friction = 1.0f;
float verticalDamping = 1.0f; float verticalDamping = 1.0f;
bool grounded = false; bool grounded = false;
bool yCollided = false;
float gravityScale = 1.0f; float gravityScale = 1.0f;
bool crouching = false; bool crouching = false;
float stepHeight = 0.5f; float stepHeight = 0.5f;

View file

@ -119,7 +119,9 @@ static void calc_collision(
} }
} }
bool PhysicsSolver::calcCollisionNegY(Hitbox& hitbox, const glm::vec3& half) { bool PhysicsSolver::calcCollisionNegY(
Hitbox& hitbox, const glm::vec3& half, float dt
) {
auto& pos = hitbox.position; auto& pos = hitbox.position;
auto& vel = hitbox.velocity; auto& vel = hitbox.velocity;
@ -140,8 +142,8 @@ bool PhysicsSolver::calcCollisionNegY(Hitbox& hitbox, const glm::vec3& half) {
pos.y = newy; pos.y = newy;
} }
hitbox.groundVelocity = box->position - box->prevPosition; hitbox.groundVelocity = box->position - box->prevPosition;
if (vel.y < 0.0f) { if (vel.y < hitbox.groundVelocity.y / dt) {
vel.y = 0.0f; vel.y = hitbox.groundVelocity.y / dt * (1.0f - E);
if (hitbox.groundMaterial.empty() && !box->material.empty()) { if (hitbox.groundMaterial.empty() && !box->material.empty()) {
hitbox.groundMaterial = box->material; hitbox.groundMaterial = box->material;
} }
@ -185,9 +187,9 @@ void PhysicsSolver::calcCollisions(
glm::vec3& vel, glm::vec3& vel,
glm::vec3& pos, glm::vec3& pos,
const glm::vec3& half, const glm::vec3& half,
float stepHeight float stepHeight,
float dt
) { ) {
hitbox.yCollided = false;
stepHeight = calc_step_height(chunks, pos, half, stepHeight); stepHeight = calc_step_height(chunks, pos, half, stepHeight);
auto prevPos = pos; auto prevPos = pos;
@ -202,7 +204,7 @@ void PhysicsSolver::calcCollisions(
calc_collision<2, 1, 0, 1>(hitbox, chunks, solidHitboxes, half, stepHeight); calc_collision<2, 1, 0, 1>(hitbox, chunks, solidHitboxes, half, stepHeight);
pos.x = xpos; pos.x = xpos;
if (calcCollisionNegY(hitbox, half)) { if (calcCollisionNegY(hitbox, half, dt)) {
hitbox.grounded = true; hitbox.grounded = true;
} }
@ -221,7 +223,6 @@ void PhysicsSolver::calcCollisions(
if (pos.y >= newy) { if (pos.y >= newy) {
vel.y = 0.0f; vel.y = 0.0f;
pos.y = newy; pos.y = newy;
hitbox.yCollided = true;
} }
break; break;
} }
@ -245,10 +246,6 @@ void PhysicsSolver::calcCollisions(
} }
} }
if (hitbox.yCollided) {
pos.y = prevPos.y;
}
// step on // step on
if (stepHeight > 0.0 && vel.y <= 0.0f) { if (stepHeight > 0.0 && vel.y <= 0.0f) {
AABB boxAABB = AABB(pos - half, pos + half); AABB boxAABB = AABB(pos - half, pos + half);
@ -287,18 +284,8 @@ void PhysicsSolver::calcCollisions(
} }
void PhysicsSolver::calcSubstep( void PhysicsSolver::calcSubstep(
Hitbox& hitbox, Hitbox& hitbox, glm::vec3& vel, glm::vec3& pos, float dt
glm::vec3& vel,
glm::vec3& pos,
float dt,
int substeps
) { ) {
if (glm::length2(hitbox.groundVelocity) > 1e-6f) {
if (hitbox.groundVelocity.y < 0.0f) {
pos.y += hitbox.groundVelocity.y;
}
}
auto initpos = pos; auto initpos = pos;
auto half = hitbox.getHalfSize(); auto half = hitbox.getHalfSize();
float gravityScale = hitbox.gravityScale; float gravityScale = hitbox.gravityScale;
@ -309,7 +296,9 @@ void PhysicsSolver::calcSubstep(
vel, vel,
pos, pos,
half, half,
(hitbox.prevGrounded && gravityScale > 0.0f) ? hitbox.stepHeight : 0.0f (hitbox.prevGrounded && gravityScale > 0.0f) ? hitbox.stepHeight
: 0.0f,
dt
); );
} }
@ -375,9 +364,8 @@ void PhysicsSolver::step(
for (uint i = 0; i < substeps; i++) { for (uint i = 0; i < substeps; i++) {
for (auto hitbox : hitboxes) { for (auto hitbox : hitboxes) {
glm::vec3& pos = hitbox->position; glm::vec3& pos = hitbox->position;
glm::vec3& vel = hitbox->velocity;
hitbox->prevPosition = hitbox->position; hitbox->prevPosition = hitbox->position;
calcSubstep(*hitbox, vel, pos, dt, substeps); calcSubstep(*hitbox, hitbox->velocity, pos, dt);
} }
} }
@ -392,9 +380,7 @@ void PhysicsSolver::step(
if (hitbox->verticalDamping > 0.0f) { if (hitbox->verticalDamping > 0.0f) {
vel.y /= 1.0f + delta * linearDamping * hitbox->verticalDamping; vel.y /= 1.0f + delta * linearDamping * hitbox->verticalDamping;
} }
if (hitbox->prevGrounded && !hitbox->grounded) { if (!hitbox->grounded) {
auto appliedVelocity = hitbox->groundVelocity / dt;
vel += appliedVelocity;
hitbox->groundVelocity = {}; hitbox->groundVelocity = {};
} }

View file

@ -44,14 +44,13 @@ private:
glm::vec3& vel, glm::vec3& vel,
glm::vec3& pos, glm::vec3& pos,
const glm::vec3& half, const glm::vec3& half,
float stepHeight float stepHeight,
float dt
); );
void calcSubstep( void calcSubstep(Hitbox& hitbox, glm::vec3& vel, glm::vec3& pos, float dt);
Hitbox& hitbox, glm::vec3& vel, glm::vec3& pos, float dt, int substeps
);
bool calcCollisionNegY(Hitbox& hitbox, const glm::vec3& half); bool calcCollisionNegY(Hitbox& hitbox, const glm::vec3& half, float dt);
void updateSensors(Hitbox& hitbox); void updateSensors(Hitbox& hitbox);
}; };