From f33d9dab5bf05356f9a2c882537e83390a710e0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Sun, 22 Nov 2015 14:14:07 +0100 Subject: [PATCH 1/3] Fix can_move_to and rename it for more clarity Fixes #2416. The KinematicBody::can_move_to function was likely designed for two behaviours: - discrete: check if the body can "teleport" to the destination - continuous: check if the direct path to the destination is valid The continuous behaviour was however not implemented, and the discrete behaviour was broken too due to a wrong call to intersect_shape. The discrete behaviour has thus been fixed and the function renamed to can_teleport_to for more clarity. --- scene/3d/physics_body.cpp | 15 ++++----------- scene/3d/physics_body.h | 2 +- servers/physics/space_sw.cpp | 6 ++++-- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index d61859a3d06..de50484a1e2 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -1073,7 +1073,7 @@ Vector3 KinematicBody::move_to(const Vector3& p_position) { return move(p_position-get_global_transform().origin); } -bool KinematicBody::can_move_to(const Vector3& p_position, bool p_discrete) { +bool KinematicBody::can_teleport_to(const Vector3& p_position) { ERR_FAIL_COND_V(!is_inside_tree(),false); PhysicsDirectSpaceState *dss = PhysicsServer::get_singleton()->space_get_direct_state(get_world()->get_space()); @@ -1089,25 +1089,18 @@ bool KinematicBody::can_move_to(const Vector3& p_position, bool p_discrete) { if (collide_character) mask|=PhysicsDirectSpaceState::TYPE_MASK_CHARACTER_BODY; - Vector3 motion = p_position-get_global_transform().origin; Transform xform=get_global_transform(); - - if (true || p_discrete) { - - xform.origin+=motion; - motion=Vector3(); - } + xform.origin=p_position; Set exclude; exclude.insert(get_rid()); - //fill exclude list.. for(int i=0;iintersect_shape(get_shape(i)->get_rid(), xform * get_shape_transform(i),0,NULL,0,exclude,get_layer_mask(),mask); + bool col = dss->intersect_shape(get_shape(i)->get_rid(), xform * get_shape_transform(i),0,NULL,1,exclude,get_layer_mask(),mask); if (col) return false; } @@ -1205,7 +1198,7 @@ void KinematicBody::_bind_methods() { ObjectTypeDB::bind_method(_MD("move","rel_vec"),&KinematicBody::move); ObjectTypeDB::bind_method(_MD("move_to","position"),&KinematicBody::move_to); - ObjectTypeDB::bind_method(_MD("can_move_to","position"),&KinematicBody::can_move_to); + ObjectTypeDB::bind_method(_MD("can_teleport_to","position"),&KinematicBody::can_teleport_to); ObjectTypeDB::bind_method(_MD("is_colliding"),&KinematicBody::is_colliding); diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h index 66490ba9258..0e63b771187 100644 --- a/scene/3d/physics_body.h +++ b/scene/3d/physics_body.h @@ -304,7 +304,7 @@ public: Vector3 move(const Vector3& p_motion); Vector3 move_to(const Vector3& p_position); - bool can_move_to(const Vector3& p_position,bool p_discrete=false); + bool can_teleport_to(const Vector3& p_position); bool is_colliding() const; Vector3 get_collision_pos() const; Vector3 get_collision_normal() const; diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp index ba1c737530f..4b59f2d0ba3 100644 --- a/servers/physics/space_sw.cpp +++ b/servers/physics/space_sw.cpp @@ -175,6 +175,10 @@ int PhysicsDirectSpaceStateSW::intersect_shape(const RID& p_shape, const Transfo if (!CollisionSolverSW::solve_static(shape,p_xform,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), NULL,NULL,NULL,p_margin,0)) continue; + cc++; + + if (!r_results) + continue; r_results[cc].collider_id=col_obj->get_instance_id(); if (r_results[cc].collider_id!=0) r_results[cc].collider=ObjectDB::get_instance(r_results[cc].collider_id); @@ -183,8 +187,6 @@ int PhysicsDirectSpaceStateSW::intersect_shape(const RID& p_shape, const Transfo r_results[cc].rid=col_obj->get_self(); r_results[cc].shape=shape_idx; - cc++; - } return cc; From e57dfe26632beeaf65cf15352db57424f2094deb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Sun, 22 Nov 2015 14:21:04 +0100 Subject: [PATCH 2/3] Update doc for can_teleport_to --- doc/base/classes.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/doc/base/classes.xml b/doc/base/classes.xml index 44a7cccfe5c..ba29d534d75 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -15038,14 +15038,13 @@ returns:= "username=user&password=pass" - + - - + Returns whether the KinematicBody can be teleported to the destination given as an argument, checking all collision shapes of the body against potential colliders at the destination. From 9457211f8fd673eb5ef7d32c7ddb0157d2735753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Fri, 4 Dec 2015 09:31:01 +0100 Subject: [PATCH 3/3] Fix wrong index being used to populate r_results Regression from f33d9da. --- servers/physics/space_sw.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp index 4b59f2d0ba3..778d20d3f15 100644 --- a/servers/physics/space_sw.cpp +++ b/servers/physics/space_sw.cpp @@ -175,17 +175,17 @@ int PhysicsDirectSpaceStateSW::intersect_shape(const RID& p_shape, const Transfo if (!CollisionSolverSW::solve_static(shape,p_xform,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), NULL,NULL,NULL,p_margin,0)) continue; - cc++; + if (r_results) { + r_results[cc].collider_id=col_obj->get_instance_id(); + if (r_results[cc].collider_id!=0) + r_results[cc].collider=ObjectDB::get_instance(r_results[cc].collider_id); + else + r_results[cc].collider=NULL; + r_results[cc].rid=col_obj->get_self(); + r_results[cc].shape=shape_idx; + } - if (!r_results) - continue; - r_results[cc].collider_id=col_obj->get_instance_id(); - if (r_results[cc].collider_id!=0) - r_results[cc].collider=ObjectDB::get_instance(r_results[cc].collider_id); - else - r_results[cc].collider=NULL; - r_results[cc].rid=col_obj->get_self(); - r_results[cc].shape=shape_idx; + cc++; }