Unverified Commit 2ad7eb9b by Rémi Verschelde Committed by GitHub

Merge pull request #36079 from madmiraal/fix-35744

Normalise p_up_direction vector in move_and_slide()
parents 309adb93 c4650540
...@@ -997,6 +997,7 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_ ...@@ -997,6 +997,7 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_
Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
Vector2 body_velocity = p_linear_velocity; Vector2 body_velocity = p_linear_velocity;
Vector2 body_velocity_normal = body_velocity.normalized(); Vector2 body_velocity_normal = body_velocity.normalized();
Vector2 up_direction = p_up_direction.normalized();
Vector2 current_floor_velocity = floor_velocity; Vector2 current_floor_velocity = floor_velocity;
if (on_floor && on_floor_body.is_valid()) { if (on_floor && on_floor_body.is_valid()) {
...@@ -1043,11 +1044,11 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const ...@@ -1043,11 +1044,11 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
colliders.push_back(collision); colliders.push_back(collision);
motion = collision.remainder; motion = collision.remainder;
if (p_up_direction == Vector2()) { if (up_direction == Vector2()) {
//all is a wall //all is a wall
on_wall = true; on_wall = true;
} else { } else {
if (Math::acos(collision.normal.dot(p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor if (Math::acos(collision.normal.dot(up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor
on_floor = true; on_floor = true;
floor_normal = collision.normal; floor_normal = collision.normal;
...@@ -1055,14 +1056,14 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const ...@@ -1055,14 +1056,14 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
floor_velocity = collision.collider_vel; floor_velocity = collision.collider_vel;
if (p_stop_on_slope) { if (p_stop_on_slope) {
if ((body_velocity_normal + p_up_direction).length() < 0.01 && collision.travel.length() < 1) { if ((body_velocity_normal + up_direction).length() < 0.01 && collision.travel.length() < 1) {
Transform2D gt = get_global_transform(); Transform2D gt = get_global_transform();
gt.elements[2] -= collision.travel.slide(p_up_direction); gt.elements[2] -= collision.travel.slide(up_direction);
set_global_transform(gt); set_global_transform(gt);
return Vector2(); return Vector2();
} }
} }
} else if (Math::acos(collision.normal.dot(-p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling } else if (Math::acos(collision.normal.dot(-up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling
on_ceiling = true; on_ceiling = true;
} else { } else {
on_wall = true; on_wall = true;
...@@ -1085,9 +1086,10 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const ...@@ -1085,9 +1086,10 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
} }
Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
Vector2 up_direction = p_up_direction.normalized();
bool was_on_floor = on_floor; bool was_on_floor = on_floor;
Vector2 ret = move_and_slide(p_linear_velocity, p_up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia); Vector2 ret = move_and_slide(p_linear_velocity, up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia);
if (!was_on_floor || p_snap == Vector2()) { if (!was_on_floor || p_snap == Vector2()) {
return ret; return ret;
} }
...@@ -1097,8 +1099,8 @@ Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_veloci ...@@ -1097,8 +1099,8 @@ Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_veloci
if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) { if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) {
bool apply = true; bool apply = true;
if (p_up_direction != Vector2()) { if (up_direction != Vector2()) {
if (Math::acos(p_up_direction.normalized().dot(col.normal)) < p_floor_max_angle) { if (Math::acos(col.normal.dot(up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) {
on_floor = true; on_floor = true;
floor_normal = col.normal; floor_normal = col.normal;
on_floor_body = col.collider_rid; on_floor_body = col.collider_rid;
...@@ -1106,7 +1108,7 @@ Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_veloci ...@@ -1106,7 +1108,7 @@ Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_veloci
if (p_stop_on_slope) { if (p_stop_on_slope) {
// move and collide may stray the object a bit because of pre un-stucking, // move and collide may stray the object a bit because of pre un-stucking,
// so only ensure that motion happens on floor direction in this case. // so only ensure that motion happens on floor direction in this case.
col.travel = p_up_direction * p_up_direction.dot(col.travel); col.travel = up_direction * up_direction.dot(col.travel);
} }
} else { } else {
......
...@@ -945,6 +945,7 @@ bool KinematicBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_ ...@@ -945,6 +945,7 @@ bool KinematicBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_
Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
Vector3 body_velocity = p_linear_velocity; Vector3 body_velocity = p_linear_velocity;
Vector3 body_velocity_normal = body_velocity.normalized(); Vector3 body_velocity_normal = body_velocity.normalized();
Vector3 up_direction = p_up_direction.normalized();
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
if (locked_axis & (1 << i)) { if (locked_axis & (1 << i)) {
...@@ -988,11 +989,11 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const ...@@ -988,11 +989,11 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const
colliders.push_back(collision); colliders.push_back(collision);
motion = collision.remainder; motion = collision.remainder;
if (p_up_direction == Vector3()) { if (up_direction == Vector3()) {
//all is a wall //all is a wall
on_wall = true; on_wall = true;
} else { } else {
if (Math::acos(collision.normal.dot(p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor if (Math::acos(collision.normal.dot(up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor
on_floor = true; on_floor = true;
floor_normal = collision.normal; floor_normal = collision.normal;
...@@ -1000,14 +1001,14 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const ...@@ -1000,14 +1001,14 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const
floor_velocity = collision.collider_vel; floor_velocity = collision.collider_vel;
if (p_stop_on_slope) { if (p_stop_on_slope) {
if ((body_velocity_normal + p_up_direction).length() < 0.01 && collision.travel.length() < 1) { if ((body_velocity_normal + up_direction).length() < 0.01 && collision.travel.length() < 1) {
Transform gt = get_global_transform(); Transform gt = get_global_transform();
gt.origin -= collision.travel.slide(p_up_direction); gt.origin -= collision.travel.slide(up_direction);
set_global_transform(gt); set_global_transform(gt);
return Vector3(); return Vector3();
} }
} }
} else if (Math::acos(collision.normal.dot(-p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling } else if (Math::acos(collision.normal.dot(-up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling
on_ceiling = true; on_ceiling = true;
} else { } else {
on_wall = true; on_wall = true;
...@@ -1036,9 +1037,10 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const ...@@ -1036,9 +1037,10 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const
} }
Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
Vector3 up_direction = p_up_direction.normalized();
bool was_on_floor = on_floor; bool was_on_floor = on_floor;
Vector3 ret = move_and_slide(p_linear_velocity, p_up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia); Vector3 ret = move_and_slide(p_linear_velocity, up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia);
if (!was_on_floor || p_snap == Vector3()) { if (!was_on_floor || p_snap == Vector3()) {
return ret; return ret;
} }
...@@ -1048,8 +1050,8 @@ Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_veloci ...@@ -1048,8 +1050,8 @@ Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_veloci
if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) { if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) {
bool apply = true; bool apply = true;
if (p_up_direction != Vector3()) { if (up_direction != Vector3()) {
if (Math::acos(p_up_direction.normalized().dot(col.normal)) < p_floor_max_angle) { if (Math::acos(col.normal.dot(up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) {
on_floor = true; on_floor = true;
floor_normal = col.normal; floor_normal = col.normal;
on_floor_body = col.collider_rid; on_floor_body = col.collider_rid;
...@@ -1057,7 +1059,7 @@ Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_veloci ...@@ -1057,7 +1059,7 @@ Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_veloci
if (p_stop_on_slope) { if (p_stop_on_slope) {
// move and collide may stray the object a bit because of pre un-stucking, // move and collide may stray the object a bit because of pre un-stucking,
// so only ensure that motion happens on floor direction in this case. // so only ensure that motion happens on floor direction in this case.
col.travel = col.travel.project(p_up_direction); col.travel = col.travel.project(up_direction);
} }
} else { } else {
apply = false; //snapped with floor direction, but did not snap to a floor, do not snap. apply = false; //snapped with floor direction, but did not snap to a floor, do not snap.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment