diff options
-rw-r--r-- | scene/2d/ray_cast_2d.cpp | 34 | ||||
-rw-r--r-- | scene/2d/ray_cast_2d.h | 9 | ||||
-rw-r--r-- | scene/3d/camera.cpp | 35 | ||||
-rw-r--r-- | scene/3d/camera.h | 8 | ||||
-rw-r--r-- | scene/3d/ray_cast.cpp | 62 | ||||
-rw-r--r-- | scene/3d/ray_cast.h | 18 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 6 | ||||
-rw-r--r-- | servers/physics/space_sw.cpp | 26 | ||||
-rw-r--r-- | servers/physics_2d/space_2d_sw.cpp | 38 | ||||
-rw-r--r-- | servers/physics_2d/space_2d_sw.h | 12 | ||||
-rw-r--r-- | servers/physics_2d_server.cpp | 46 | ||||
-rw-r--r-- | servers/physics_2d_server.h | 25 | ||||
-rw-r--r-- | servers/physics_server.cpp | 50 | ||||
-rw-r--r-- | servers/physics_server.h | 17 |
14 files changed, 280 insertions, 106 deletions
diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index 255d2d38d5..9582c08110 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -209,7 +209,7 @@ void RayCast2D::_update_raycast_state() { Physics2DDirectSpaceState::RayResult rr; - if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, collision_mask)) { + if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, collision_mask, collide_with_bodies, collide_with_areas)) { collided = true; against = rr.collider_id; @@ -258,6 +258,26 @@ void RayCast2D::clear_exceptions() { exclude.clear(); } +void RayCast2D::set_collide_with_areas(bool p_clip) { + + collide_with_areas = p_clip; +} + +bool RayCast2D::is_collide_with_areas_enabled() const { + + return collide_with_areas; +} + +void RayCast2D::set_collide_with_bodies(bool p_clip) { + + collide_with_bodies = p_clip; +} + +bool RayCast2D::is_collide_with_bodies_enabled() const { + + return collide_with_bodies; +} + void RayCast2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &RayCast2D::set_enabled); @@ -291,10 +311,20 @@ void RayCast2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_exclude_parent_body", "mask"), &RayCast2D::set_exclude_parent_body); ClassDB::bind_method(D_METHOD("get_exclude_parent_body"), &RayCast2D::get_exclude_parent_body); + ClassDB::bind_method(D_METHOD("set_collide_with_areas", "enable"), &RayCast2D::set_collide_with_areas); + ClassDB::bind_method(D_METHOD("is_collide_with_areas_enabled"), &RayCast2D::is_collide_with_areas_enabled); + + ClassDB::bind_method(D_METHOD("set_collide_with_bodies", "enable"), &RayCast2D::set_collide_with_bodies); + ClassDB::bind_method(D_METHOD("is_collide_with_bodies_enabled"), &RayCast2D::is_collide_with_bodies_enabled); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exclude_parent"), "set_exclude_parent_body", "get_exclude_parent_body"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "cast_to"), "set_cast_to", "get_cast_to"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_mask", "get_collision_mask"); + + ADD_GROUP("Collide With", "collide_with"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collide_with_areas", "is_collide_with_areas_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collide_with_bodies", "is_collide_with_bodies_enabled"); } RayCast2D::RayCast2D() { @@ -306,4 +336,6 @@ RayCast2D::RayCast2D() { collision_mask = 1; cast_to = Vector2(0, 50); exclude_parent_body = true; + collide_with_bodies = true; + collide_with_areas = false; } diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h index 0850cdc7cc..a438be87b6 100644 --- a/scene/2d/ray_cast_2d.h +++ b/scene/2d/ray_cast_2d.h @@ -49,12 +49,21 @@ class RayCast2D : public Node2D { Vector2 cast_to; + bool collide_with_areas; + bool collide_with_bodies; + protected: void _notification(int p_what); void _update_raycast_state(); static void _bind_methods(); public: + void set_collide_with_areas(bool p_clip); + bool is_collide_with_areas_enabled() const; + + void set_collide_with_bodies(bool p_clip); + bool is_collide_with_bodies_enabled() const; + void set_enabled(bool p_enabled); bool is_enabled() const; diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index 8d820baa4d..bcd015875b 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -742,7 +742,7 @@ void ClippedCamera::_notification(int p_what) { xf.orthonormalize(); float csafe, cunsafe; - if (dspace->cast_motion(pyramid_shape, xf, cam_pos - ray_from, margin, csafe, cunsafe, exclude, collision_mask)) { + if (dspace->cast_motion(pyramid_shape, xf, cam_pos - ray_from, margin, csafe, cunsafe, exclude, collision_mask, clip_to_bodies, clip_to_areas)) { clip_offset = cam_pos.distance_to(ray_from + (cam_pos - ray_from).normalized() * csafe); } @@ -811,6 +811,27 @@ void ClippedCamera::clear_exceptions() { exclude.clear(); } + +void ClippedCamera::set_clip_to_areas(bool p_clip) { + + clip_to_areas = p_clip; +} + +bool ClippedCamera::is_clip_to_areas_enabled() const { + + return clip_to_areas; +} + +void ClippedCamera::set_clip_to_bodies(bool p_clip) { + + clip_to_bodies = p_clip; +} + +bool ClippedCamera::is_clip_to_bodies_enabled() const { + + return clip_to_bodies; +} + void ClippedCamera::_bind_methods() { ClassDB::bind_method(D_METHOD("set_margin", "margin"), &ClippedCamera::set_margin); @@ -831,11 +852,21 @@ void ClippedCamera::_bind_methods() { ClassDB::bind_method(D_METHOD("remove_exception_rid", "rid"), &ClippedCamera::remove_exception_rid); ClassDB::bind_method(D_METHOD("remove_exception", "node"), &ClippedCamera::remove_exception); + ClassDB::bind_method(D_METHOD("set_clip_to_areas", "enable"), &ClippedCamera::set_clip_to_areas); + ClassDB::bind_method(D_METHOD("is_clip_to_areas_enabled"), &ClippedCamera::is_clip_to_areas_enabled); + + ClassDB::bind_method(D_METHOD("set_clip_to_bodies", "enable"), &ClippedCamera::set_clip_to_bodies); + ClassDB::bind_method(D_METHOD("is_clip_to_bodies_enabled"), &ClippedCamera::is_clip_to_bodies_enabled); + ClassDB::bind_method(D_METHOD("clear_exceptions"), &ClippedCamera::clear_exceptions); ADD_PROPERTY(PropertyInfo(Variant::REAL, "margin", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_margin", "get_margin"); ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_mode", "get_process_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); + + ADD_GROUP("Clip To", "clip_to"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_to_areas", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_clip_to_areas", "is_clip_to_areas_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_to_bodies", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_clip_to_bodies", "is_clip_to_bodies_enabled"); } ClippedCamera::ClippedCamera() { margin = 0; @@ -846,6 +877,8 @@ ClippedCamera::ClippedCamera() { set_notify_local_transform(Engine::get_singleton()->is_editor_hint()); points.resize(5); pyramid_shape = PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONVEX_POLYGON); + clip_to_areas = false; + clip_to_bodies = true; } ClippedCamera::~ClippedCamera() { PhysicsServer::get_singleton()->free(pyramid_shape); diff --git a/scene/3d/camera.h b/scene/3d/camera.h index 002d23b8fe..a35c9d6e7f 100644 --- a/scene/3d/camera.h +++ b/scene/3d/camera.h @@ -190,6 +190,8 @@ private: float margin; float clip_offset; uint32_t collision_mask; + bool clip_to_areas; + bool clip_to_bodies; Set<RID> exclude; @@ -201,6 +203,12 @@ protected: virtual Transform get_camera_transform() const; public: + void set_clip_to_areas(bool p_clip); + bool is_clip_to_areas_enabled() const; + + void set_clip_to_bodies(bool p_clip); + bool is_clip_to_bodies_enabled() const; + void set_margin(float p_margin); float get_margin() const; diff --git a/scene/3d/ray_cast.cpp b/scene/3d/ray_cast.cpp index e1897c0187..b846a5b6c0 100644 --- a/scene/3d/ray_cast.cpp +++ b/scene/3d/ray_cast.cpp @@ -49,26 +49,6 @@ Vector3 RayCast::get_cast_to() const { return cast_to; } -void RayCast::set_collide_with_bodies(bool p_enable) { - - collide_with_bodies = p_enable; -} - -bool RayCast::get_collide_with_bodies() const { - - return collide_with_bodies; -} - -void RayCast::set_collide_with_areas(bool p_enable) { - - collide_with_areas = p_enable; -} - -bool RayCast::get_collide_with_areas() const { - - return collide_with_areas; -} - void RayCast::set_collision_mask(uint32_t p_mask) { collision_mask = p_mask; @@ -279,6 +259,26 @@ void RayCast::clear_exceptions() { exclude.clear(); } +void RayCast::set_collide_with_areas(bool p_clip) { + + collide_with_areas = p_clip; +} + +bool RayCast::is_collide_with_areas_enabled() const { + + return collide_with_areas; +} + +void RayCast::set_collide_with_bodies(bool p_clip) { + + collide_with_bodies = p_clip; +} + +bool RayCast::is_collide_with_bodies_enabled() const { + + return collide_with_bodies; +} + void RayCast::_bind_methods() { ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &RayCast::set_enabled); @@ -287,12 +287,6 @@ void RayCast::_bind_methods() { ClassDB::bind_method(D_METHOD("set_cast_to", "local_point"), &RayCast::set_cast_to); ClassDB::bind_method(D_METHOD("get_cast_to"), &RayCast::get_cast_to); - ClassDB::bind_method(D_METHOD("set_collide_with_bodies", "enable"), &RayCast::set_collide_with_bodies); - ClassDB::bind_method(D_METHOD("get_collide_with_bodies"), &RayCast::get_collide_with_bodies); - - ClassDB::bind_method(D_METHOD("set_collide_with_areas", "enable"), &RayCast::set_collide_with_areas); - ClassDB::bind_method(D_METHOD("get_collide_with_areas"), &RayCast::get_collide_with_areas); - ClassDB::bind_method(D_METHOD("is_colliding"), &RayCast::is_colliding); ClassDB::bind_method(D_METHOD("force_raycast_update"), &RayCast::force_raycast_update); @@ -318,12 +312,20 @@ void RayCast::_bind_methods() { ClassDB::bind_method(D_METHOD("set_exclude_parent_body", "mask"), &RayCast::set_exclude_parent_body); ClassDB::bind_method(D_METHOD("get_exclude_parent_body"), &RayCast::get_exclude_parent_body); + ClassDB::bind_method(D_METHOD("set_collide_with_areas", "enable"), &RayCast::set_collide_with_areas); + ClassDB::bind_method(D_METHOD("is_collide_with_areas_enabled"), &RayCast::is_collide_with_areas_enabled); + + ClassDB::bind_method(D_METHOD("set_collide_with_bodies", "enable"), &RayCast::set_collide_with_bodies); + ClassDB::bind_method(D_METHOD("is_collide_with_bodies_enabled"), &RayCast::is_collide_with_bodies_enabled); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exclude_parent"), "set_exclude_parent_body", "get_exclude_parent_body"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "cast_to"), "set_cast_to", "get_cast_to"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies"), "set_collide_with_bodies", "get_collide_with_bodies"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas"), "set_collide_with_areas", "get_collide_with_areas"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); + + ADD_GROUP("Collide With", "collide_with"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collide_with_areas", "is_collide_with_areas_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collide_with_bodies", "is_collide_with_bodies_enabled"); } void RayCast::_create_debug_shape() { @@ -396,8 +398,8 @@ RayCast::RayCast() { against_shape = 0; collision_mask = 1; cast_to = Vector3(0, -1, 0); - collide_with_bodies = true; - collide_with_areas = false; debug_shape = NULL; exclude_parent_body = true; + collide_with_areas = false; + collide_with_bodies = true; } diff --git a/scene/3d/ray_cast.h b/scene/3d/ray_cast.h index 417cb884cc..e95382e1fe 100644 --- a/scene/3d/ray_cast.h +++ b/scene/3d/ray_cast.h @@ -45,9 +45,6 @@ class RayCast : public Spatial { Vector3 collision_normal; Vector3 cast_to; - bool collide_with_bodies; - bool collide_with_areas; - Set<RID> exclude; uint32_t collision_mask; @@ -60,24 +57,27 @@ class RayCast : public Spatial { void _update_debug_shape(); void _clear_debug_shape(); + bool collide_with_areas; + bool collide_with_bodies; + protected: void _notification(int p_what); void _update_raycast_state(); static void _bind_methods(); public: + void set_collide_with_areas(bool p_clip); + bool is_collide_with_areas_enabled() const; + + void set_collide_with_bodies(bool p_clip); + bool is_collide_with_bodies_enabled() const; + void set_enabled(bool p_enabled); bool is_enabled() const; void set_cast_to(const Vector3 &p_point); Vector3 get_cast_to() const; - void set_collide_with_bodies(bool p_enable); - bool get_collide_with_bodies() const; - - void set_collide_with_areas(bool p_enable); - bool get_collide_with_areas() const; - void set_collision_mask(uint32_t p_mask); uint32_t get_collision_mask() const; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index e43c2da02d..f92b6e7583 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -444,7 +444,7 @@ void Viewport::_notification(int p_what) { Vector2 point = get_canvas_transform().affine_inverse().xform(pos); Physics2DDirectSpaceState::ShapeResult res[64]; - int rc = ss2d->intersect_point(point, res, 64, Set<RID>(), 0xFFFFFFFF, true); + int rc = ss2d->intersect_point(point, res, 64, Set<RID>(), 0xFFFFFFFF, true, true, true); for (int i = 0; i < rc; i++) { if (res[i].collider_id && res[i].collider) { @@ -527,7 +527,7 @@ void Viewport::_notification(int p_what) { PhysicsDirectSpaceState *space = PhysicsServer::get_singleton()->space_get_direct_state(find_world()->get_space()); if (space) { - bool col = space->intersect_ray(from, from + dir * 10000, result, Set<RID>(), 0xFFFFFFFF, true); + bool col = space->intersect_ray(from, from + dir * 10000, result, Set<RID>(), 0xFFFFFFFF, true, true, true); ObjectID new_collider = 0; if (col) { @@ -563,7 +563,7 @@ void Viewport::_notification(int p_what) { PhysicsDirectSpaceState *space = PhysicsServer::get_singleton()->space_get_direct_state(find_world()->get_space()); if (space) { - bool col = space->intersect_ray(from, from + dir * 10000, result, Set<RID>(), 0xFFFFFFFF, true); + bool col = space->intersect_ray(from, from + dir * 10000, result, Set<RID>(), 0xFFFFFFFF, true, true, true); ObjectID new_collider = 0; if (col) { CollisionObject *co = Object::cast_to<CollisionObject>(result.collider); diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp index a4ad19eba7..cae2e6fb00 100644 --- a/servers/physics/space_sw.cpp +++ b/servers/physics/space_sw.cpp @@ -34,9 +34,19 @@ #include "physics_server_sw.h" #include "project_settings.h" -_FORCE_INLINE_ static bool _can_collide_with(CollisionObjectSW *p_object, uint32_t p_collision_mask) { +_FORCE_INLINE_ static bool _can_collide_with(CollisionObjectSW *p_object, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { - return p_object->get_collision_layer() & p_collision_mask; + if (!(p_object->get_collision_layer() & p_collision_mask)) { + return false; + } + + if (p_object->get_type() == CollisionObjectSW::TYPE_AREA && !p_collide_with_areas) + return false; + + if (p_object->get_type() == CollisionObjectSW::TYPE_BODY && !p_collide_with_bodies) + return false; + + return true; } int PhysicsDirectSpaceStateSW::intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { @@ -52,7 +62,7 @@ int PhysicsDirectSpaceStateSW::intersect_point(const Vector3 &p_point, ShapeResu if (cc >= p_result_max) break; - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask)) + if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) continue; //area can't be picked by ray (default) @@ -105,7 +115,7 @@ bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3 &p_from, const Vecto for (int i = 0; i < amount; i++) { - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask)) + if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) continue; if (p_pick_ray && !(static_cast<CollisionObjectSW *>(space->intersection_query_results[i])->is_ray_pickable())) @@ -182,7 +192,7 @@ int PhysicsDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transfo if (cc >= p_result_max) break; - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask)) + if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) continue; //area can't be picked by ray (default) @@ -242,7 +252,7 @@ bool PhysicsDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform for (int i = 0; i < amount; i++) { - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask)) + if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) continue; if (p_exclude.has(space->intersection_query_results[i]->get_self())) @@ -356,7 +366,7 @@ bool PhysicsDirectSpaceStateSW::collide_shape(RID p_shape, const Transform &p_sh for (int i = 0; i < amount; i++) { - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask)) + if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) continue; const CollisionObjectSW *col_obj = space->intersection_query_results[i]; @@ -422,7 +432,7 @@ bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform &p_shape_ for (int i = 0; i < amount; i++) { - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask)) + if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) continue; const CollisionObjectSW *col_obj = space->intersection_query_results[i]; diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index 6e45951f42..ecebd09436 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -34,12 +34,22 @@ #include "pair.h" #include "physics_2d_server_sw.h" -_FORCE_INLINE_ static bool _can_collide_with(CollisionObject2DSW *p_object, uint32_t p_collision_mask) { +_FORCE_INLINE_ static bool _can_collide_with(CollisionObject2DSW *p_object, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { - return p_object->get_collision_layer() & p_collision_mask; + if (!(p_object->get_collision_layer() & p_collision_mask)) { + return false; + } + + if (p_object->get_type() == CollisionObject2DSW::TYPE_AREA && !p_collide_with_areas) + return false; + + if (p_object->get_type() == CollisionObject2DSW::TYPE_BODY && !p_collide_with_bodies) + return false; + + return true; } -int Physics2DDirectSpaceStateSW::intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_pick_point) { +int Physics2DDirectSpaceStateSW::intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point) { if (p_result_max <= 0) return 0; @@ -54,7 +64,7 @@ int Physics2DDirectSpaceStateSW::intersect_point(const Vector2 &p_point, ShapeRe for (int i = 0; i < amount; i++) { - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask)) + if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) continue; if (p_exclude.has(space->intersection_query_results[i]->get_self())) @@ -90,7 +100,7 @@ int Physics2DDirectSpaceStateSW::intersect_point(const Vector2 &p_point, ShapeRe return cc; } -bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_collision_mask) { +bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { ERR_FAIL_COND_V(space->locked, false); @@ -112,7 +122,7 @@ bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2 &p_from, const Vec for (int i = 0; i < amount; i++) { - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask)) + if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) continue; if (p_exclude.has(space->intersection_query_results[i]->get_self())) @@ -170,7 +180,7 @@ bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2 &p_from, const Vec return true; } -int Physics2DDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask) { +int Physics2DDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (p_result_max <= 0) return 0; @@ -190,7 +200,7 @@ int Physics2DDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Trans if (cc >= p_result_max) break; - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask)) + if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) continue; if (p_exclude.has(space->intersection_query_results[i]->get_self())) @@ -215,7 +225,7 @@ int Physics2DDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Trans return cc; } -bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask) { +bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { Shape2DSW *shape = Physics2DServerSW::singletonsw->shape_owner.get(p_shape); ERR_FAIL_COND_V(!shape, false); @@ -236,7 +246,7 @@ bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transfor for (int i = 0; i < amount; i++) { - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask)) + if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) continue; if (p_exclude.has(space->intersection_query_results[i]->get_self())) @@ -299,7 +309,7 @@ bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transfor return true; } -bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_mask) { +bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (p_result_max <= 0) return 0; @@ -330,7 +340,7 @@ bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Transform2D & for (int i = 0; i < amount; i++) { - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask)) + if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) continue; const CollisionObject2DSW *col_obj = space->intersection_query_results[i]; @@ -388,7 +398,7 @@ static void _rest_cbk_result(const Vector2 &p_point_A, const Vector2 &p_point_B, rd->best_shape = rd->shape; } -bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask) { +bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { Shape2DSW *shape = Physics2DServerSW::singletonsw->shape_owner.get(p_shape); ERR_FAIL_COND_V(!shape, 0); @@ -406,7 +416,7 @@ bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Transform2D &p_sh for (int i = 0; i < amount; i++) { - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask)) + if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) continue; const CollisionObject2DSW *col_obj = space->intersection_query_results[i]; diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h index 1247317b03..6e2e025185 100644 --- a/servers/physics_2d/space_2d_sw.h +++ b/servers/physics_2d/space_2d_sw.h @@ -48,12 +48,12 @@ class Physics2DDirectSpaceStateSW : public Physics2DDirectSpaceState { public: Space2DSW *space; - virtual int intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_pick_point = false); - virtual bool intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF); - virtual int intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF); - virtual bool cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF); - virtual bool collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF); - virtual bool rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF); + virtual int intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_point = false); + virtual bool intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); + virtual int intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); + virtual bool cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); + virtual bool collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); + virtual bool rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); Physics2DDirectSpaceStateSW(); }; diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp index 37c4bc83ad..a51b938541 100644 --- a/servers/physics_2d_server.cpp +++ b/servers/physics_2d_server.cpp @@ -203,6 +203,22 @@ Vector<RID> Physics2DShapeQueryParameters::get_exclude() const { return ret; } +void Physics2DShapeQueryParameters::set_collide_with_bodies(bool p_enable) { + collide_with_bodies = p_enable; +} + +bool Physics2DShapeQueryParameters::is_collide_with_bodies_enabled() const { + return collide_with_bodies; +} + +void Physics2DShapeQueryParameters::set_collide_with_areas(bool p_enable) { + collide_with_areas = p_enable; +} + +bool Physics2DShapeQueryParameters::is_collide_with_areas_enabled() const { + return collide_with_areas; +} + void Physics2DShapeQueryParameters::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shape", "shape"), &Physics2DShapeQueryParameters::set_shape); @@ -224,6 +240,12 @@ void Physics2DShapeQueryParameters::_bind_methods() { ClassDB::bind_method(D_METHOD("set_exclude", "exclude"), &Physics2DShapeQueryParameters::set_exclude); ClassDB::bind_method(D_METHOD("get_exclude"), &Physics2DShapeQueryParameters::get_exclude); + ClassDB::bind_method(D_METHOD("set_collide_with_bodies", "enable"), &Physics2DShapeQueryParameters::set_collide_with_bodies); + ClassDB::bind_method(D_METHOD("is_collide_with_bodies_enabled"), &Physics2DShapeQueryParameters::is_collide_with_bodies_enabled); + + ClassDB::bind_method(D_METHOD("set_collide_with_areas", "enable"), &Physics2DShapeQueryParameters::set_collide_with_areas); + ClassDB::bind_method(D_METHOD("is_collide_with_areas_enabled"), &Physics2DShapeQueryParameters::is_collide_with_areas_enabled); + ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_layer", "get_collision_layer"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude", PROPERTY_HINT_NONE, itos(Variant::_RID) + ":"), "set_exclude", "get_exclude"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "margin", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_margin", "get_margin"); @@ -231,22 +253,26 @@ void Physics2DShapeQueryParameters::_bind_methods() { //ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", ""); // FIXME: Lacks a getter ADD_PROPERTY(PropertyInfo(Variant::_RID, "shape_rid"), "set_shape_rid", "get_shape_rid"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform"), "set_transform", "get_transform"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies"), "set_collide_with_bodies", "is_collide_with_bodies_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas"), "set_collide_with_areas", "is_collide_with_areas_enabled"); } Physics2DShapeQueryParameters::Physics2DShapeQueryParameters() { margin = 0; collision_mask = 0x7FFFFFFF; + collide_with_bodies = true; + collide_with_areas = false; } -Dictionary Physics2DDirectSpaceState::_intersect_ray(const Vector2 &p_from, const Vector2 &p_to, const Vector<RID> &p_exclude, uint32_t p_layers) { +Dictionary Physics2DDirectSpaceState::_intersect_ray(const Vector2 &p_from, const Vector2 &p_to, const Vector<RID> &p_exclude, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas) { RayResult inters; Set<RID> exclude; for (int i = 0; i < p_exclude.size(); i++) exclude.insert(p_exclude[i]); - bool res = intersect_ray(p_from, p_to, inters, exclude, p_layers); + bool res = intersect_ray(p_from, p_to, inters, exclude, p_layers, p_collide_with_bodies, p_collide_with_areas); if (!res) return Dictionary(); @@ -267,7 +293,7 @@ Array Physics2DDirectSpaceState::_intersect_shape(const Ref<Physics2DShapeQueryP Vector<ShapeResult> sr; sr.resize(p_max_results); - int rc = intersect_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, sr.ptrw(), sr.size(), p_shape_query->exclude, p_shape_query->collision_mask); + int rc = intersect_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, sr.ptrw(), sr.size(), p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); Array ret; ret.resize(rc); for (int i = 0; i < rc; i++) { @@ -287,7 +313,7 @@ Array Physics2DDirectSpaceState::_intersect_shape(const Ref<Physics2DShapeQueryP Array Physics2DDirectSpaceState::_cast_motion(const Ref<Physics2DShapeQueryParameters> &p_shape_query) { float closest_safe, closest_unsafe; - bool res = cast_motion(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, closest_safe, closest_unsafe, p_shape_query->exclude, p_shape_query->collision_mask); + bool res = cast_motion(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, closest_safe, closest_unsafe, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); if (!res) return Array(); Array ret; @@ -297,7 +323,7 @@ Array Physics2DDirectSpaceState::_cast_motion(const Ref<Physics2DShapeQueryParam return ret; } -Array Physics2DDirectSpaceState::_intersect_point(const Vector2 &p_point, int p_max_results, const Vector<RID> &p_exclude, uint32_t p_layers) { +Array Physics2DDirectSpaceState::_intersect_point(const Vector2 &p_point, int p_max_results, const Vector<RID> &p_exclude, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas) { Set<RID> exclude; for (int i = 0; i < p_exclude.size(); i++) @@ -306,7 +332,7 @@ Array Physics2DDirectSpaceState::_intersect_point(const Vector2 &p_point, int p_ Vector<ShapeResult> ret; ret.resize(p_max_results); - int rc = intersect_point(p_point, ret.ptrw(), ret.size(), exclude, p_layers); + int rc = intersect_point(p_point, ret.ptrw(), ret.size(), exclude, p_layers, p_collide_with_bodies, p_collide_with_areas); if (rc == 0) return Array(); @@ -330,7 +356,7 @@ Array Physics2DDirectSpaceState::_collide_shape(const Ref<Physics2DShapeQueryPar Vector<Vector2> ret; ret.resize(p_max_results * 2); int rc = 0; - bool res = collide_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, ret.ptrw(), p_max_results, rc, p_shape_query->exclude, p_shape_query->collision_mask); + bool res = collide_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, ret.ptrw(), p_max_results, rc, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); if (!res) return Array(); Array r; @@ -343,7 +369,7 @@ Dictionary Physics2DDirectSpaceState::_get_rest_info(const Ref<Physics2DShapeQue ShapeRestInfo sri; - bool res = rest_info(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, &sri, p_shape_query->exclude, p_shape_query->collision_mask); + bool res = rest_info(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, &sri, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); Dictionary r; if (!res) return r; @@ -364,8 +390,8 @@ Physics2DDirectSpaceState::Physics2DDirectSpaceState() { void Physics2DDirectSpaceState::_bind_methods() { - ClassDB::bind_method(D_METHOD("intersect_point", "point", "max_results", "exclude", "collision_layer"), &Physics2DDirectSpaceState::_intersect_point, DEFVAL(32), DEFVAL(Array()), DEFVAL(0x7FFFFFFF)); - ClassDB::bind_method(D_METHOD("intersect_ray", "from", "to", "exclude", "collision_layer"), &Physics2DDirectSpaceState::_intersect_ray, DEFVAL(Array()), DEFVAL(0x7FFFFFFF)); + ClassDB::bind_method(D_METHOD("intersect_point", "point", "max_results", "exclude", "collision_layer", "collide_with_bodies", "collide_with_areas"), &Physics2DDirectSpaceState::_intersect_point, DEFVAL(32), DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(true), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("intersect_ray", "from", "to", "exclude", "collision_layer", "collide_with_bodies", "collide_with_areas"), &Physics2DDirectSpaceState::_intersect_ray, DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(true), DEFVAL(false)); ClassDB::bind_method(D_METHOD("intersect_shape", "shape", "max_results"), &Physics2DDirectSpaceState::_intersect_shape, DEFVAL(32)); ClassDB::bind_method(D_METHOD("cast_motion", "shape"), &Physics2DDirectSpaceState::_cast_motion); ClassDB::bind_method(D_METHOD("collide_shape", "shape", "max_results"), &Physics2DDirectSpaceState::_collide_shape, DEFVAL(32)); diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h index f42d9868f0..82b4eb75d8 100644 --- a/servers/physics_2d_server.h +++ b/servers/physics_2d_server.h @@ -107,6 +107,9 @@ class Physics2DShapeQueryParameters : public Reference { Set<RID> exclude; uint32_t collision_mask; + bool collide_with_bodies; + bool collide_with_areas; + protected: static void _bind_methods(); @@ -127,6 +130,12 @@ public: void set_collision_mask(int p_collision_mask); int get_collision_mask() const; + void set_collide_with_bodies(bool p_enable); + bool is_collide_with_bodies_enabled() const; + + void set_collide_with_areas(bool p_enable); + bool is_collide_with_areas_enabled() const; + void set_exclude(const Vector<RID> &p_exclude); Vector<RID> get_exclude() const; @@ -137,9 +146,9 @@ class Physics2DDirectSpaceState : public Object { GDCLASS(Physics2DDirectSpaceState, Object); - Dictionary _intersect_ray(const Vector2 &p_from, const Vector2 &p_to, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_layers = 0); + Dictionary _intersect_ray(const Vector2 &p_from, const Vector2 &p_to, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_layers = 0, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); - Array _intersect_point(const Vector2 &p_point, int p_max_results = 32, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_layers = 0); + Array _intersect_point(const Vector2 &p_point, int p_max_results = 32, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_layers = 0, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); Array _intersect_shape(const Ref<Physics2DShapeQueryParameters> &p_shape_query, int p_max_results = 32); Array _cast_motion(const Ref<Physics2DShapeQueryParameters> &p_shape_query); Array _collide_shape(const Ref<Physics2DShapeQueryParameters> &p_shape_query, int p_max_results = 32); @@ -160,7 +169,7 @@ public: Variant metadata; }; - virtual bool intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF) = 0; + virtual bool intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; struct ShapeResult { @@ -171,13 +180,13 @@ public: Variant metadata; }; - virtual int intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_pick_point = false) = 0; + virtual int intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_point = false) = 0; - virtual int intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF) = 0; + virtual int intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; - virtual bool cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF) = 0; + virtual bool cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; - virtual bool collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, float p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF) = 0; + virtual bool collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, float p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; struct ShapeRestInfo { @@ -190,7 +199,7 @@ public: Variant metadata; }; - virtual bool rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF) = 0; + virtual bool rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; Physics2DDirectSpaceState(); }; diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp index 94990e8495..deb3cd9bbe 100644 --- a/servers/physics_server.cpp +++ b/servers/physics_server.cpp @@ -200,6 +200,22 @@ Vector<RID> PhysicsShapeQueryParameters::get_exclude() const { return ret; } +void PhysicsShapeQueryParameters::set_collide_with_bodies(bool p_enable) { + collide_with_bodies = p_enable; +} + +bool PhysicsShapeQueryParameters::is_collide_with_bodies_enabled() const { + return collide_with_bodies; +} + +void PhysicsShapeQueryParameters::set_collide_with_areas(bool p_enable) { + collide_with_areas = p_enable; +} + +bool PhysicsShapeQueryParameters::is_collide_with_areas_enabled() const { + return collide_with_areas; +} + void PhysicsShapeQueryParameters::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shape", "shape"), &PhysicsShapeQueryParameters::set_shape); @@ -218,18 +234,28 @@ void PhysicsShapeQueryParameters::_bind_methods() { ClassDB::bind_method(D_METHOD("set_exclude", "exclude"), &PhysicsShapeQueryParameters::set_exclude); ClassDB::bind_method(D_METHOD("get_exclude"), &PhysicsShapeQueryParameters::get_exclude); + ClassDB::bind_method(D_METHOD("set_collide_with_bodies", "enable"), &PhysicsShapeQueryParameters::set_collide_with_bodies); + ClassDB::bind_method(D_METHOD("is_collide_with_bodies_enabled"), &PhysicsShapeQueryParameters::is_collide_with_bodies_enabled); + + ClassDB::bind_method(D_METHOD("set_collide_with_areas", "enable"), &PhysicsShapeQueryParameters::set_collide_with_areas); + ClassDB::bind_method(D_METHOD("is_collide_with_areas_enabled"), &PhysicsShapeQueryParameters::is_collide_with_areas_enabled); + ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude", PROPERTY_HINT_NONE, itos(Variant::_RID) + ":"), "set_exclude", "get_exclude"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "margin", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_margin", "get_margin"); //ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", ""); // FIXME: Lacks a getter ADD_PROPERTY(PropertyInfo(Variant::_RID, "shape_rid"), "set_shape_rid", "get_shape_rid"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "transform"), "set_transform", "get_transform"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies"), "set_collide_with_bodies", "is_collide_with_bodies_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas"), "set_collide_with_areas", "is_collide_with_areas_enabled"); } PhysicsShapeQueryParameters::PhysicsShapeQueryParameters() { margin = 0; collision_mask = 0x7FFFFFFF; + collide_with_bodies = true; + collide_with_areas = false; } ///////////////////////////////////// @@ -287,11 +313,11 @@ Dictionary PhysicsDirectSpaceState::_intersect_ray(const Vector3 &p_from, const return d; } -Array PhysicsDirectSpaceState::_intersect_shape(const Ref<PhysicsShapeQueryParameters> &p_shape_query, bool p_collide_with_bodies, bool p_collide_with_areas, int p_max_results) { +Array PhysicsDirectSpaceState::_intersect_shape(const Ref<PhysicsShapeQueryParameters> &p_shape_query, int p_max_results) { Vector<ShapeResult> sr; sr.resize(p_max_results); - int rc = intersect_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->margin, sr.ptrw(), sr.size(), p_shape_query->exclude, p_shape_query->collision_mask, p_collide_with_bodies, p_collide_with_areas); + int rc = intersect_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->margin, sr.ptrw(), sr.size(), p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); Array ret; ret.resize(rc); for (int i = 0; i < rc; i++) { @@ -307,10 +333,10 @@ Array PhysicsDirectSpaceState::_intersect_shape(const Ref<PhysicsShapeQueryParam return ret; } -Array PhysicsDirectSpaceState::_cast_motion(const Ref<PhysicsShapeQueryParameters> &p_shape_query, const Vector3 &p_motion, bool p_collide_with_bodies, bool p_collide_with_areas) { +Array PhysicsDirectSpaceState::_cast_motion(const Ref<PhysicsShapeQueryParameters> &p_shape_query, const Vector3 &p_motion) { float closest_safe, closest_unsafe; - bool res = cast_motion(p_shape_query->shape, p_shape_query->transform, p_motion, p_shape_query->margin, closest_safe, closest_unsafe, p_shape_query->exclude, p_shape_query->collision_mask, p_collide_with_bodies, p_collide_with_areas); + bool res = cast_motion(p_shape_query->shape, p_shape_query->transform, p_motion, p_shape_query->margin, closest_safe, closest_unsafe, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); if (!res) return Array(); Array ret; @@ -319,12 +345,12 @@ Array PhysicsDirectSpaceState::_cast_motion(const Ref<PhysicsShapeQueryParameter ret[1] = closest_unsafe; return ret; } -Array PhysicsDirectSpaceState::_collide_shape(const Ref<PhysicsShapeQueryParameters> &p_shape_query, bool p_collide_with_bodies, bool p_collide_with_areas, int p_max_results) { +Array PhysicsDirectSpaceState::_collide_shape(const Ref<PhysicsShapeQueryParameters> &p_shape_query, int p_max_results) { Vector<Vector3> ret; ret.resize(p_max_results * 2); int rc = 0; - bool res = collide_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->margin, ret.ptrw(), p_max_results, rc, p_shape_query->exclude, p_shape_query->collision_mask, p_collide_with_bodies, p_collide_with_areas); + bool res = collide_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->margin, ret.ptrw(), p_max_results, rc, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); if (!res) return Array(); Array r; @@ -333,11 +359,11 @@ Array PhysicsDirectSpaceState::_collide_shape(const Ref<PhysicsShapeQueryParamet r[i] = ret[i]; return r; } -Dictionary PhysicsDirectSpaceState::_get_rest_info(const Ref<PhysicsShapeQueryParameters> &p_shape_query, bool p_collide_with_bodies, bool p_collide_with_areas) { +Dictionary PhysicsDirectSpaceState::_get_rest_info(const Ref<PhysicsShapeQueryParameters> &p_shape_query) { ShapeRestInfo sri; - bool res = rest_info(p_shape_query->shape, p_shape_query->transform, p_shape_query->margin, &sri, p_shape_query->exclude, p_shape_query->collision_mask, p_collide_with_bodies, p_collide_with_areas); + bool res = rest_info(p_shape_query->shape, p_shape_query->transform, p_shape_query->margin, &sri, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); Dictionary r; if (!res) return r; @@ -361,10 +387,10 @@ void PhysicsDirectSpaceState::_bind_methods() { //ClassDB::bind_method(D_METHOD("intersect_shape","shape","xform","result_max","exclude","umask"),&PhysicsDirectSpaceState::_intersect_shape,DEFVAL(Array()),DEFVAL(0)); ClassDB::bind_method(D_METHOD("intersect_ray", "from", "to", "exclude", "collision_mask", "collide_with_bodies", "collide_with_areas"), &PhysicsDirectSpaceState::_intersect_ray, DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(true), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("intersect_shape", "shape", "collide_with_bodies", "collide_with_areas", "max_results"), &PhysicsDirectSpaceState::_intersect_shape, DEFVAL(true), DEFVAL(false), DEFVAL(32)); - ClassDB::bind_method(D_METHOD("cast_motion", "shape", "motion", "collide_with_bodies", "collide_with_areas"), &PhysicsDirectSpaceState::_cast_motion, DEFVAL(true), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("collide_shape", "shape", "collide_with_bodies", "collide_with_areas", "max_results"), &PhysicsDirectSpaceState::_collide_shape, DEFVAL(true), DEFVAL(false), DEFVAL(32)); - ClassDB::bind_method(D_METHOD("get_rest_info", "shape", "collide_with_bodies", "collide_with_areas"), &PhysicsDirectSpaceState::_get_rest_info, DEFVAL(true), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("intersect_shape", "shape", "max_results"), &PhysicsDirectSpaceState::_intersect_shape, DEFVAL(32)); + ClassDB::bind_method(D_METHOD("cast_motion", "shape", "motion"), &PhysicsDirectSpaceState::_cast_motion); + ClassDB::bind_method(D_METHOD("collide_shape", "shape", "max_results"), &PhysicsDirectSpaceState::_collide_shape, DEFVAL(32)); + ClassDB::bind_method(D_METHOD("get_rest_info", "shape"), &PhysicsDirectSpaceState::_get_rest_info); } int PhysicsShapeQueryResult::get_result_count() const { diff --git a/servers/physics_server.h b/servers/physics_server.h index 3bd47a6601..f2aa33a6cc 100644 --- a/servers/physics_server.h +++ b/servers/physics_server.h @@ -108,6 +108,9 @@ class PhysicsShapeQueryParameters : public Reference { Set<RID> exclude; uint32_t collision_mask; + bool collide_with_bodies; + bool collide_with_areas; + protected: static void _bind_methods(); @@ -128,6 +131,12 @@ public: void set_exclude(const Vector<RID> &p_exclude); Vector<RID> get_exclude() const; + void set_collide_with_bodies(bool p_enable); + bool is_collide_with_bodies_enabled() const; + + void set_collide_with_areas(bool p_enable); + bool is_collide_with_areas_enabled() const; + PhysicsShapeQueryParameters(); }; @@ -137,10 +146,10 @@ class PhysicsDirectSpaceState : public Object { private: Dictionary _intersect_ray(const Vector3 &p_from, const Vector3 &p_to, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_collision_mask = 0, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); - Array _intersect_shape(const Ref<PhysicsShapeQueryParameters> &p_shape_query, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, int p_max_results = 32); - Array _cast_motion(const Ref<PhysicsShapeQueryParameters> &p_shape_query, const Vector3 &p_motion, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); - Array _collide_shape(const Ref<PhysicsShapeQueryParameters> &p_shape_query, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, int p_max_results = 32); - Dictionary _get_rest_info(const Ref<PhysicsShapeQueryParameters> &p_shape_query, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); + Array _intersect_shape(const Ref<PhysicsShapeQueryParameters> &p_shape_query, int p_max_results = 32); + Array _cast_motion(const Ref<PhysicsShapeQueryParameters> &p_shape_query, const Vector3 &p_motion); + Array _collide_shape(const Ref<PhysicsShapeQueryParameters> &p_shape_query, int p_max_results = 32); + Dictionary _get_rest_info(const Ref<PhysicsShapeQueryParameters> &p_shape_query); protected: static void _bind_methods(); |