From c02fb271fd54ecda331968d2269af79a6007dcb1 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Fri, 10 Aug 2018 13:06:34 -0300 Subject: [PATCH] apply a threshold for floor angle, fixes #16037, fixes #15632 --- scene/2d/physics_body_2d.cpp | 7 +++++-- scene/3d/physics_body.cpp | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 85bef4e7f5a..8758ffef9f1 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -1204,6 +1204,9 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_ return colliding; } +//so, if you pass 45 as limit, avoid numerical precision erros when angle is 45. +#define FLOOR_ANGLE_THRESHOLD 0.01 + Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, bool p_infinite_inertia, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) { Vector2 floor_motion = floor_velocity; @@ -1257,7 +1260,7 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const //all is a wall on_wall = true; } else { - if (collision.normal.dot(p_floor_direction) >= Math::cos(p_floor_max_angle)) { //floor + if (collision.normal.dot(p_floor_direction) >= Math::cos(p_floor_max_angle + FLOOR_ANGLE_THRESHOLD)) { //floor on_floor = true; on_floor_body = collision.collider_rid; @@ -1272,7 +1275,7 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const set_global_transform(gt); return Vector2(); } - } else if (collision.normal.dot(-p_floor_direction) >= Math::cos(p_floor_max_angle)) { //ceiling + } else if (collision.normal.dot(-p_floor_direction) >= Math::cos(p_floor_max_angle + FLOOR_ANGLE_THRESHOLD)) { //ceiling on_ceiling = true; } else { on_wall = true; diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index 1c9099ec8b4..84a0fb9b1df 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -1125,6 +1125,9 @@ bool KinematicBody::move_and_collide(const Vector3 &p_motion, bool p_infinite_in return colliding; } +//so, if you pass 45 as limit, avoid numerical precision erros when angle is 45. +#define FLOOR_ANGLE_THRESHOLD 0.01 + Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { Vector3 lv = p_linear_velocity; @@ -1157,7 +1160,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve //all is a wall on_wall = true; } else { - if (collision.normal.dot(p_floor_direction) >= Math::cos(p_floor_max_angle)) { //floor + if (collision.normal.dot(p_floor_direction) >= Math::cos(p_floor_max_angle + FLOOR_ANGLE_THRESHOLD)) { //floor on_floor = true; floor_velocity = collision.collider_vel; @@ -1171,7 +1174,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve set_global_transform(gt); return floor_velocity - p_floor_direction * p_floor_direction.dot(floor_velocity); } - } else if (collision.normal.dot(-p_floor_direction) >= Math::cos(p_floor_max_angle)) { //ceiling + } else if (collision.normal.dot(-p_floor_direction) >= Math::cos(p_floor_max_angle + FLOOR_ANGLE_THRESHOLD)) { //ceiling on_ceiling = true; } else { on_wall = true;