summaryrefslogtreecommitdiff
path: root/scene/2d/physics_body_2d.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/2d/physics_body_2d.cpp')
-rw-r--r--scene/2d/physics_body_2d.cpp83
1 files changed, 40 insertions, 43 deletions
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 5f56f86029..9a10255acc 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -54,13 +54,14 @@ PhysicsBody2D::~PhysicsBody2D() {
}
}
-Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_motion, bool p_test_only, real_t p_margin) {
- PhysicsServer2D::MotionResult result;
-
+Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_linear_velocity, bool p_test_only, real_t p_margin) {
// Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky.
double delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
- if (move_and_collide(p_motion * delta, result, p_margin, p_test_only)) {
+ PhysicsServer2D::MotionParameters parameters(get_global_transform(), p_linear_velocity * delta, p_margin);
+
+ PhysicsServer2D::MotionResult result;
+ if (move_and_collide(parameters, result, p_test_only)) {
// Create a new instance when the cached reference is invalid or still in use in script.
if (motion_cache.is_null() || motion_cache->reference_get_count() > 1) {
motion_cache.instantiate();
@@ -74,18 +75,18 @@ Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_motion, bool p_t
return Ref<KinematicCollision2D>();
}
-bool PhysicsBody2D::move_and_collide(const Vector2 &p_motion, PhysicsServer2D::MotionResult &r_result, real_t p_margin, bool p_test_only, bool p_cancel_sliding, bool p_collide_separation_ray, const Set<RID> &p_exclude) {
+bool PhysicsBody2D::move_and_collide(const PhysicsServer2D::MotionParameters &p_parameters, PhysicsServer2D::MotionResult &r_result, bool p_test_only, bool p_cancel_sliding) {
if (is_only_update_transform_changes_enabled()) {
ERR_PRINT("Move functions do not work together with 'sync to physics' option. Please read the documentation.");
}
- Transform2D gt = get_global_transform();
- bool colliding = PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_margin, &r_result, p_collide_separation_ray, p_exclude);
+
+ bool colliding = PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), p_parameters, &r_result);
// Restore direction of motion to be along original motion,
// in order to avoid sliding due to recovery,
// but only if collision depth is low enough to avoid tunneling.
if (p_cancel_sliding) {
- real_t motion_length = p_motion.length();
+ real_t motion_length = p_parameters.motion.length();
real_t precision = 0.001;
if (colliding) {
@@ -93,7 +94,7 @@ bool PhysicsBody2D::move_and_collide(const Vector2 &p_motion, PhysicsServer2D::M
// so even in normal resting cases the depth can be a bit more than the margin.
precision += motion_length * (r_result.collision_unsafe_fraction - r_result.collision_safe_fraction);
- if (r_result.collision_depth > (real_t)p_margin + precision) {
+ if (r_result.collision_depth > p_parameters.margin + precision) {
p_cancel_sliding = false;
}
}
@@ -102,7 +103,7 @@ bool PhysicsBody2D::move_and_collide(const Vector2 &p_motion, PhysicsServer2D::M
// When motion is null, recovery is the resulting motion.
Vector2 motion_normal;
if (motion_length > CMP_EPSILON) {
- motion_normal = p_motion / motion_length;
+ motion_normal = p_parameters.motion / motion_length;
}
// Check depth of recovery.
@@ -111,15 +112,16 @@ bool PhysicsBody2D::move_and_collide(const Vector2 &p_motion, PhysicsServer2D::M
real_t recovery_length = recovery.length();
// Fixes cases where canceling slide causes the motion to go too deep into the ground,
// because we're only taking rest information into account and not general recovery.
- if (recovery_length < (real_t)p_margin + precision) {
+ if (recovery_length < p_parameters.margin + precision) {
// Apply adjustment to motion.
r_result.travel = motion_normal * projected_length;
- r_result.remainder = p_motion - r_result.travel;
+ r_result.remainder = p_parameters.motion - r_result.travel;
}
}
}
if (!p_test_only) {
+ Transform2D gt = p_parameters.from;
gt.elements[2] += r_result.travel;
set_global_transform(gt);
}
@@ -127,7 +129,7 @@ bool PhysicsBody2D::move_and_collide(const Vector2 &p_motion, PhysicsServer2D::M
return colliding;
}
-bool PhysicsBody2D::test_move(const Transform2D &p_from, const Vector2 &p_motion, const Ref<KinematicCollision2D> &r_collision, real_t p_margin) {
+bool PhysicsBody2D::test_move(const Transform2D &p_from, const Vector2 &p_linear_velocity, const Ref<KinematicCollision2D> &r_collision, real_t p_margin) {
ERR_FAIL_COND_V(!is_inside_tree(), false);
PhysicsServer2D::MotionResult *r = nullptr;
@@ -139,7 +141,9 @@ bool PhysicsBody2D::test_move(const Transform2D &p_from, const Vector2 &p_motion
// Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky.
double delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
- return PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion * delta, p_margin, r);
+ PhysicsServer2D::MotionParameters parameters(p_from, p_linear_velocity * delta, p_margin);
+
+ return PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), parameters, r);
}
TypedArray<PhysicsBody2D> PhysicsBody2D::get_collision_exceptions() {
@@ -1083,10 +1087,11 @@ bool CharacterBody2D::move_and_slide() {
on_wall = false;
if (!current_platform_velocity.is_equal_approx(Vector2())) {
+ PhysicsServer2D::MotionParameters parameters(get_global_transform(), current_platform_velocity * delta, margin);
+ parameters.exclude_bodies.insert(platform_rid);
+
PhysicsServer2D::MotionResult floor_result;
- Set<RID> exclude;
- exclude.insert(platform_rid);
- if (move_and_collide(current_platform_velocity * delta, floor_result, margin, false, false, false, exclude)) {
+ if (move_and_collide(parameters, floor_result, false, false)) {
motion_results.push_back(floor_result);
_set_collision_direction(floor_result);
}
@@ -1138,11 +1143,13 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
Vector2 last_travel;
for (int iteration = 0; iteration < max_slides; ++iteration) {
- PhysicsServer2D::MotionResult result;
+ PhysicsServer2D::MotionParameters parameters(get_global_transform(), motion, margin);
- Vector2 prev_position = get_global_transform().elements[2];
+ Vector2 prev_position = parameters.from.elements[2];
+
+ PhysicsServer2D::MotionResult result;
+ bool collided = move_and_collide(parameters, result, false, !sliding_enabled);
- bool collided = move_and_collide(motion, result, margin, false, !sliding_enabled);
last_motion = result.travel;
if (collided) {
@@ -1283,9 +1290,11 @@ void CharacterBody2D::_move_and_slide_free(double p_delta) {
bool first_slide = true;
for (int iteration = 0; iteration < max_slides; ++iteration) {
+ PhysicsServer2D::MotionParameters parameters(get_global_transform(), motion, margin);
+
PhysicsServer2D::MotionResult result;
+ bool collided = move_and_collide(parameters, result, false, false);
- bool collided = move_and_collide(motion, result, margin, false, false);
last_motion = result.travel;
if (collided) {
@@ -1327,10 +1336,11 @@ void CharacterBody2D::_snap_on_floor(bool was_on_floor, bool vel_dir_facing_up)
// Snap by at least collision margin to keep floor state consistent.
real_t length = MAX(floor_snap_length, margin);
- Transform2D gt = get_global_transform();
+ PhysicsServer2D::MotionParameters parameters(get_global_transform(), -up_direction * length, margin);
+ parameters.collide_separation_ray = true;
+
PhysicsServer2D::MotionResult result;
- if (move_and_collide(-up_direction * length, result, margin, true, false, true)) {
- bool apply = true;
+ if (move_and_collide(parameters, result, true, false)) {
if (result.get_angle(up_direction) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) {
on_floor = true;
floor_normal = result.collision_normal;
@@ -1345,13 +1355,9 @@ void CharacterBody2D::_snap_on_floor(bool was_on_floor, bool vel_dir_facing_up)
result.travel = Vector2();
}
}
- } else {
- apply = false;
- }
- if (apply) {
- gt.elements[2] += result.travel;
- set_global_transform(gt);
+ parameters.from.elements[2] += result.travel;
+ set_global_transform(parameters.from);
}
}
}
@@ -1364,8 +1370,11 @@ bool CharacterBody2D::_on_floor_if_snapped(bool was_on_floor, bool vel_dir_facin
// Snap by at least collision margin to keep floor state consistent.
real_t length = MAX(floor_snap_length, margin);
+ PhysicsServer2D::MotionParameters parameters(get_global_transform(), -up_direction * length, margin);
+ parameters.collide_separation_ray = true;
+
PhysicsServer2D::MotionResult result;
- if (move_and_collide(-up_direction * length, result, margin, true, false, true)) {
+ if (move_and_collide(parameters, result, true, false)) {
if (result.get_angle(up_direction) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) {
return true;
}
@@ -1806,16 +1815,4 @@ void KinematicCollision2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_collider_shape"), &KinematicCollision2D::get_collider_shape);
ClassDB::bind_method(D_METHOD("get_collider_shape_index"), &KinematicCollision2D::get_collider_shape_index);
ClassDB::bind_method(D_METHOD("get_collider_velocity"), &KinematicCollision2D::get_collider_velocity);
-
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "", "get_position");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "normal"), "", "get_normal");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "travel"), "", "get_travel");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "remainder"), "", "get_remainder");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "local_shape"), "", "get_local_shape");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider"), "", "get_collider");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_id"), "", "get_collider_id");
- ADD_PROPERTY(PropertyInfo(Variant::RID, "collider_rid"), "", "get_collider_rid");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider_shape"), "", "get_collider_shape");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_shape_index"), "", "get_collider_shape_index");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "collider_velocity"), "", "get_collider_velocity");
}