From 7494a8c3c6738ae212cc9ec62eb478056b846e3d Mon Sep 17 00:00:00 2001 From: Karol Walasek Date: Tue, 9 Aug 2016 19:52:15 +0200 Subject: [PATCH 1/2] Added force_raycast_update GDScript method for RayCast[2D] --- scene/2d/ray_cast_2d.cpp | 60 ++++++++++++++++++++++------------------ scene/2d/ray_cast_2d.h | 3 ++ scene/3d/ray_cast.cpp | 60 ++++++++++++++++++++++------------------ scene/3d/ray_cast.h | 2 ++ 4 files changed, 71 insertions(+), 54 deletions(-) diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index b5d62adfb4a..bd7f4faae5f 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -187,39 +187,44 @@ void RayCast2D::_notification(int p_what) { if (!enabled) break; - - - Ref w2d = get_world_2d(); - ERR_BREAK( w2d.is_null() ); - - Physics2DDirectSpaceState *dss = Physics2DServer::get_singleton()->space_get_direct_state(w2d->get_space()); - ERR_BREAK( !dss ); - - Matrix32 gt = get_global_transform(); - - Vector2 to = cast_to; - if (to==Vector2()) - to=Vector2(0,0.01); - - Physics2DDirectSpaceState::RayResult rr; - - if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude,layer_mask,type_mask)) { - - collided=true; - against=rr.collider_id; - collision_point=rr.position; - collision_normal=rr.normal; - against_shape=rr.shape; - } else { - collided=false; - } - + _update_raycast_state(); } break; } } +void RayCast2D::_update_raycast_state() { + Ref w2d = get_world_2d(); + ERR_FAIL_COND( w2d.is_null() ); + + Physics2DDirectSpaceState *dss = Physics2DServer::get_singleton()->space_get_direct_state(w2d->get_space()); + ERR_FAIL_COND( !dss ); + + Matrix32 gt = get_global_transform(); + + Vector2 to = cast_to; + if (to==Vector2()) + to=Vector2(0,0.01); + + Physics2DDirectSpaceState::RayResult rr; + + if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude,layer_mask,type_mask)) { + + collided=true; + against=rr.collider_id; + collision_point=rr.position; + collision_normal=rr.normal; + against_shape=rr.shape; + } else { + collided=false; + } +} + +void RayCast2D::force_raycast_update() { + _update_raycast_state(); +} + void RayCast2D::add_exception_rid(const RID& p_rid) { exclude.insert(p_rid); @@ -265,6 +270,7 @@ void RayCast2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_cast_to"),&RayCast2D::get_cast_to); ObjectTypeDB::bind_method(_MD("is_colliding"),&RayCast2D::is_colliding); + ObjectTypeDB::bind_method(_MD("force_raycast_update"),&RayCast2D::force_raycast_update); ObjectTypeDB::bind_method(_MD("get_collider"),&RayCast2D::get_collider); ObjectTypeDB::bind_method(_MD("get_collider_shape"),&RayCast2D::get_collider_shape); diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h index e1caa8b63e8..9bdcc2e199e 100644 --- a/scene/2d/ray_cast_2d.h +++ b/scene/2d/ray_cast_2d.h @@ -52,6 +52,7 @@ class RayCast2D : public Node2D { protected: void _notification(int p_what); + void _update_raycast_state(); static void _bind_methods(); public: @@ -70,6 +71,8 @@ public: void set_exclude_parent_body(bool p_exclude_parent_body); bool get_exclude_parent_body() const; + void force_raycast_update(); + bool is_colliding() const; Object *get_collider() const; int get_collider_shape() const; diff --git a/scene/3d/ray_cast.cpp b/scene/3d/ray_cast.cpp index 1acda8d1f8d..2b8df8265e1 100644 --- a/scene/3d/ray_cast.cpp +++ b/scene/3d/ray_cast.cpp @@ -134,39 +134,44 @@ void RayCast::_notification(int p_what) { if (!enabled) break; - - - Ref w3d = get_world(); - ERR_BREAK( w3d.is_null() ); - - PhysicsDirectSpaceState *dss = PhysicsServer::get_singleton()->space_get_direct_state(w3d->get_space()); - ERR_BREAK( !dss ); - - Transform gt = get_global_transform(); - - Vector3 to = cast_to; - if (to==Vector3()) - to=Vector3(0,0.01,0); - - PhysicsDirectSpaceState::RayResult rr; - - if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude, layer_mask, type_mask)) { - - collided=true; - against=rr.collider_id; - collision_point=rr.position; - collision_normal=rr.normal; - against_shape=rr.shape; - } else { - collided=false; - } - + _update_raycast_state(); } break; } } +void RayCast::_update_raycast_state(){ + Ref w3d = get_world(); + ERR_FAIL_COND( w3d.is_null() ); + + PhysicsDirectSpaceState *dss = PhysicsServer::get_singleton()->space_get_direct_state(w3d->get_space()); + ERR_FAIL_COND( !dss ); + + Transform gt = get_global_transform(); + + Vector3 to = cast_to; + if (to==Vector3()) + to=Vector3(0,0.01,0); + + PhysicsDirectSpaceState::RayResult rr; + + if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude, layer_mask, type_mask)) { + + collided=true; + against=rr.collider_id; + collision_point=rr.position; + collision_normal=rr.normal; + against_shape=rr.shape; + } else { + collided=false; + } +} + +void RayCast::force_raycast_update() { + _update_raycast_state(); +} + void RayCast::add_exception_rid(const RID& p_rid) { exclude.insert(p_rid); @@ -212,6 +217,7 @@ void RayCast::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_cast_to"),&RayCast::get_cast_to); ObjectTypeDB::bind_method(_MD("is_colliding"),&RayCast::is_colliding); + ObjectTypeDB::bind_method(_MD("force_raycast_update"),&RayCast::force_raycast_update); ObjectTypeDB::bind_method(_MD("get_collider"),&RayCast::get_collider); ObjectTypeDB::bind_method(_MD("get_collider_shape"),&RayCast::get_collider_shape); diff --git a/scene/3d/ray_cast.h b/scene/3d/ray_cast.h index 4f6514e61b2..47553f08ed4 100644 --- a/scene/3d/ray_cast.h +++ b/scene/3d/ray_cast.h @@ -53,6 +53,7 @@ class RayCast : public Spatial { protected: void _notification(int p_what); + void _update_raycast_state(); static void _bind_methods(); public: @@ -68,6 +69,7 @@ public: void set_type_mask(uint32_t p_mask); uint32_t get_type_mask() const; + void force_raycast_update(); bool is_colliding() const; Object *get_collider() const; int get_collider_shape() const; From 8d57640d3745084d5c4abc4e6926298c2f4a3fb4 Mon Sep 17 00:00:00 2001 From: Karol Walasek Date: Mon, 3 Oct 2016 11:35:40 +0200 Subject: [PATCH 2/2] Added general notes on RayCast[2D] updating behaviour and force_raycast_update() --- doc/base/classes.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/base/classes.xml b/doc/base/classes.xml index c18cba09a47..d5784dfe4a7 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -31869,6 +31869,8 @@ RayCast can ignore some objects by adding them to the exception list via [code]add_exception[/code], setting proper filtering with layers, or by filtering object types with type masks. Only enabled raycasts will be able to query the space and report collisions! + + RayCast calculates intersection every fixed frame (see [Node]), and the result is cached so it can be used later until the next frame. If multiple queries are required between fixed frames (or during the same frame) use [method force_raycast_update] after adjusting the raycast. @@ -31889,6 +31891,11 @@ Removes all collision exception for this ray. + + + Updates the collision information in case if this object's properties changed during the current frame (for example position, rotation or the cast_point). Note, [code]set_enabled[/code] is not required for this to work. + + @@ -32007,6 +32014,8 @@ RayCast2D can ignore some objects by adding them to the exception list via [code]add_exception[/code], setting proper filtering with layers, or by filtering object types with type masks. Only enabled raycasts will be able to query the space and report collisions! + + RayCast2D calculates intersection every fixed frame (see [Node]), and the result is cached so it can be used later until the next frame. If multiple queries are required between fixed frames (or during the same frame) use [method force_raycast_update] after adjusting the raycast. @@ -32027,6 +32036,11 @@ Removes all collision exception for this ray. + + + Updates the collision information in case if this object's properties changed during the current frame (for example position, rotation or the cast_point). Note, [code]set_enabled[/code] is not required for this to work. + +