From 0b98834b772c8e753b2a31508cf105ae555d6000 Mon Sep 17 00:00:00 2001 From: Andrea Catania Date: Tue, 21 Aug 2018 17:37:51 +0200 Subject: [PATCH] Added ray / shape / point / motion / rest cast exclusion of area and or body --- modules/bullet/godot_result_callbacks.cpp | 51 ++++++++++++++++++++++- modules/bullet/godot_result_callbacks.h | 44 ++++++++++++++----- modules/bullet/space_bullet.cpp | 26 ++++++------ modules/bullet/space_bullet.h | 12 +++--- scene/3d/ray_cast.cpp | 32 +++++++++++++- scene/3d/ray_cast.h | 8 ++++ servers/physics/space_sw.cpp | 12 +++--- servers/physics/space_sw.h | 12 +++--- servers/physics_server.cpp | 32 +++++++------- servers/physics_server.h | 22 +++++----- 10 files changed, 182 insertions(+), 69 deletions(-) diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp index 85178bf83cb..534034d7075 100644 --- a/modules/bullet/godot_result_callbacks.cpp +++ b/modules/bullet/godot_result_callbacks.cpp @@ -30,6 +30,7 @@ #include "godot_result_callbacks.h" +#include "area_bullet.h" #include "bullet_types_converter.h" #include "collision_object_bullet.h" #include "rigid_body_bullet.h" @@ -51,11 +52,23 @@ bool GodotClosestRayResultCallback::needsCollision(btBroadphaseProxy *proxy0) co if (needs) { btCollisionObject *btObj = static_cast(proxy0->m_clientObject); CollisionObjectBullet *gObj = static_cast(btObj->getUserPointer()); + + if (CollisionObjectBullet::TYPE_AREA == gObj->getType()) { + if (!collide_with_areas) + return false; + } else { + if (!collide_with_bodies) + return false; + } + if (m_pickRay && !gObj->is_ray_pickable()) { return false; - } else if (m_exclude->has(gObj->get_self())) { + } + + if (m_exclude->has(gObj->get_self())) { return false; } + return true; } else { return false; @@ -124,6 +137,15 @@ bool GodotClosestConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) if (needs) { btCollisionObject *btObj = static_cast(proxy0->m_clientObject); CollisionObjectBullet *gObj = static_cast(btObj->getUserPointer()); + + if (CollisionObjectBullet::TYPE_AREA == gObj->getType()) { + if (!collide_with_areas) + return false; + } else { + if (!collide_with_bodies) + return false; + } + if (m_exclude->has(gObj->get_self())) { return false; } @@ -144,6 +166,15 @@ bool GodotAllContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) co if (needs) { btCollisionObject *btObj = static_cast(proxy0->m_clientObject); CollisionObjectBullet *gObj = static_cast(btObj->getUserPointer()); + + if (CollisionObjectBullet::TYPE_AREA == gObj->getType()) { + if (!collide_with_areas) + return false; + } else { + if (!collide_with_bodies) + return false; + } + if (m_exclude->has(gObj->get_self())) { return false; } @@ -189,6 +220,15 @@ bool GodotContactPairContactResultCallback::needsCollision(btBroadphaseProxy *pr if (needs) { btCollisionObject *btObj = static_cast(proxy0->m_clientObject); CollisionObjectBullet *gObj = static_cast(btObj->getUserPointer()); + + if (CollisionObjectBullet::TYPE_AREA == gObj->getType()) { + if (!collide_with_areas) + return false; + } else { + if (!collide_with_bodies) + return false; + } + if (m_exclude->has(gObj->get_self())) { return false; } @@ -218,6 +258,15 @@ bool GodotRestInfoContactResultCallback::needsCollision(btBroadphaseProxy *proxy if (needs) { btCollisionObject *btObj = static_cast(proxy0->m_clientObject); CollisionObjectBullet *gObj = static_cast(btObj->getUserPointer()); + + if (CollisionObjectBullet::TYPE_AREA == gObj->getType()) { + if (!collide_with_areas) + return false; + } else { + if (!collide_with_bodies) + return false; + } + if (m_exclude->has(gObj->get_self())) { return false; } diff --git a/modules/bullet/godot_result_callbacks.h b/modules/bullet/godot_result_callbacks.h index 363051f24c3..3948f43c008 100644 --- a/modules/bullet/godot_result_callbacks.h +++ b/modules/bullet/godot_result_callbacks.h @@ -56,12 +56,17 @@ struct GodotClosestRayResultCallback : public btCollisionWorld::ClosestRayResult bool m_pickRay; int m_shapeId; + bool collide_with_bodies; + bool collide_with_areas; + public: - GodotClosestRayResultCallback(const btVector3 &rayFromWorld, const btVector3 &rayToWorld, const Set *p_exclude) : + GodotClosestRayResultCallback(const btVector3 &rayFromWorld, const btVector3 &rayToWorld, const Set *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) : btCollisionWorld::ClosestRayResultCallback(rayFromWorld, rayToWorld), m_exclude(p_exclude), m_pickRay(false), - m_shapeId(0) {} + m_shapeId(0), + collide_with_bodies(p_collide_with_bodies), + collide_with_areas(p_collide_with_areas) {} virtual bool needsCollision(btBroadphaseProxy *proxy0) const; @@ -108,9 +113,14 @@ public: const Set *m_exclude; int m_shapeId; - GodotClosestConvexResultCallback(const btVector3 &convexFromWorld, const btVector3 &convexToWorld, const Set *p_exclude) : + bool collide_with_bodies; + bool collide_with_areas; + + GodotClosestConvexResultCallback(const btVector3 &convexFromWorld, const btVector3 &convexToWorld, const Set *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) : btCollisionWorld::ClosestConvexResultCallback(convexFromWorld, convexToWorld), - m_exclude(p_exclude) {} + m_exclude(p_exclude), + collide_with_bodies(p_collide_with_bodies), + collide_with_areas(p_collide_with_areas) {} virtual bool needsCollision(btBroadphaseProxy *proxy0) const; @@ -125,12 +135,17 @@ public: int m_count; const Set *m_exclude; - GodotAllContactResultCallback(btCollisionObject *p_self_object, PhysicsDirectSpaceState::ShapeResult *p_results, int p_resultMax, const Set *p_exclude) : + bool collide_with_bodies; + bool collide_with_areas; + + GodotAllContactResultCallback(btCollisionObject *p_self_object, PhysicsDirectSpaceState::ShapeResult *p_results, int p_resultMax, const Set *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) : m_self_object(p_self_object), m_results(p_results), m_exclude(p_exclude), m_resultMax(p_resultMax), - m_count(0) {} + m_count(0), + collide_with_bodies(p_collide_with_bodies), + collide_with_areas(p_collide_with_areas) {} virtual bool needsCollision(btBroadphaseProxy *proxy0) const; @@ -146,12 +161,17 @@ public: int m_count; const Set *m_exclude; - GodotContactPairContactResultCallback(btCollisionObject *p_self_object, Vector3 *p_results, int p_resultMax, const Set *p_exclude) : + bool collide_with_bodies; + bool collide_with_areas; + + GodotContactPairContactResultCallback(btCollisionObject *p_self_object, Vector3 *p_results, int p_resultMax, const Set *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) : m_self_object(p_self_object), m_results(p_results), m_exclude(p_exclude), m_resultMax(p_resultMax), - m_count(0) {} + m_count(0), + collide_with_bodies(p_collide_with_bodies), + collide_with_areas(p_collide_with_areas) {} virtual bool needsCollision(btBroadphaseProxy *proxy0) const; @@ -167,13 +187,17 @@ public: const btCollisionObject *m_rest_info_collision_object; btVector3 m_rest_info_bt_point; const Set *m_exclude; + bool collide_with_bodies; + bool collide_with_areas; - GodotRestInfoContactResultCallback(btCollisionObject *p_self_object, PhysicsDirectSpaceState::ShapeRestInfo *p_result, const Set *p_exclude) : + GodotRestInfoContactResultCallback(btCollisionObject *p_self_object, PhysicsDirectSpaceState::ShapeRestInfo *p_result, const Set *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) : m_self_object(p_self_object), m_result(p_result), m_exclude(p_exclude), m_collided(false), - m_min_distance(0) {} + m_min_distance(0), + collide_with_bodies(p_collide_with_bodies), + collide_with_areas(p_collide_with_areas) {} virtual bool needsCollision(btBroadphaseProxy *proxy0) const; diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index e1a4e88db09..b5329bc3477 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -61,7 +61,7 @@ BulletPhysicsDirectSpaceState::BulletPhysicsDirectSpaceState(SpaceBullet *p_spac PhysicsDirectSpaceState(), space(p_space) {} -int BulletPhysicsDirectSpaceState::intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set &p_exclude, uint32_t p_collision_mask) { +int BulletPhysicsDirectSpaceState::intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (p_result_max <= 0) return 0; @@ -69,13 +69,13 @@ int BulletPhysicsDirectSpaceState::intersect_point(const Vector3 &p_point, Shape btVector3 bt_point; G_TO_B(p_point, bt_point); - btSphereShape sphere_point(0.f); + btSphereShape sphere_point(0.001f); btCollisionObject collision_object_point; collision_object_point.setCollisionShape(&sphere_point); collision_object_point.setWorldTransform(btTransform(btQuaternion::getIdentity(), bt_point)); // Setup query - GodotAllContactResultCallback btResult(&collision_object_point, r_results, p_result_max, &p_exclude); + GodotAllContactResultCallback btResult(&collision_object_point, r_results, p_result_max, &p_exclude, p_collide_with_bodies, p_collide_with_areas); btResult.m_collisionFilterGroup = 0; btResult.m_collisionFilterMask = p_collision_mask; space->dynamicsWorld->contactTest(&collision_object_point, btResult); @@ -84,7 +84,7 @@ int BulletPhysicsDirectSpaceState::intersect_point(const Vector3 &p_point, Shape return btResult.m_count; } -bool BulletPhysicsDirectSpaceState::intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set &p_exclude, uint32_t p_collision_mask, bool p_pick_ray) { +bool BulletPhysicsDirectSpaceState::intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_ray) { btVector3 btVec_from; btVector3 btVec_to; @@ -93,7 +93,7 @@ bool BulletPhysicsDirectSpaceState::intersect_ray(const Vector3 &p_from, const V G_TO_B(p_to, btVec_to); // setup query - GodotClosestRayResultCallback btResult(btVec_from, btVec_to, &p_exclude); + GodotClosestRayResultCallback btResult(btVec_from, btVec_to, &p_exclude, p_collide_with_bodies, p_collide_with_areas); btResult.m_collisionFilterGroup = 0; btResult.m_collisionFilterMask = p_collision_mask; btResult.m_pickRay = p_pick_ray; @@ -117,7 +117,7 @@ bool BulletPhysicsDirectSpaceState::intersect_ray(const Vector3 &p_from, const V } } -int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Transform &p_xform, float p_margin, ShapeResult *r_results, int p_result_max, const Set &p_exclude, uint32_t p_collision_mask) { +int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Transform &p_xform, float p_margin, ShapeResult *r_results, int p_result_max, const Set &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (p_result_max <= 0) return 0; @@ -139,7 +139,7 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra collision_object.setCollisionShape(btConvex); collision_object.setWorldTransform(bt_xform); - GodotAllContactResultCallback btQuery(&collision_object, r_results, p_result_max, &p_exclude); + GodotAllContactResultCallback btQuery(&collision_object, r_results, p_result_max, &p_exclude, p_collide_with_bodies, p_collide_with_areas); btQuery.m_collisionFilterGroup = 0; btQuery.m_collisionFilterMask = p_collision_mask; btQuery.m_closestDistanceThreshold = 0; @@ -150,7 +150,7 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra return btQuery.m_count; } -bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set &p_exclude, uint32_t p_collision_mask, ShapeRestInfo *r_info) { +bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) { ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape); btCollisionShape *btShape = shape->create_bt_shape(p_xform.basis.get_scale(), p_margin); @@ -171,7 +171,7 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf btTransform bt_xform_to(bt_xform_from); bt_xform_to.getOrigin() += bt_motion; - GodotClosestConvexResultCallback btResult(bt_xform_from.getOrigin(), bt_xform_to.getOrigin(), &p_exclude); + GodotClosestConvexResultCallback btResult(bt_xform_from.getOrigin(), bt_xform_to.getOrigin(), &p_exclude, p_collide_with_bodies, p_collide_with_areas); btResult.m_collisionFilterGroup = 0; btResult.m_collisionFilterMask = p_collision_mask; @@ -197,7 +197,7 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf } /// Returns the list of contacts pairs in this order: Local contact, other body contact -bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform &p_shape_xform, float p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set &p_exclude, uint32_t p_collision_mask) { +bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform &p_shape_xform, float p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (p_result_max <= 0) return 0; @@ -219,7 +219,7 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform & collision_object.setCollisionShape(btConvex); collision_object.setWorldTransform(bt_xform); - GodotContactPairContactResultCallback btQuery(&collision_object, r_results, p_result_max, &p_exclude); + GodotContactPairContactResultCallback btQuery(&collision_object, r_results, p_result_max, &p_exclude, p_collide_with_bodies, p_collide_with_areas); btQuery.m_collisionFilterGroup = 0; btQuery.m_collisionFilterMask = p_collision_mask; btQuery.m_closestDistanceThreshold = 0; @@ -231,7 +231,7 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform & return btQuery.m_count; } -bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set &p_exclude, uint32_t p_collision_mask) { +bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape); @@ -251,7 +251,7 @@ bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_sh collision_object.setCollisionShape(btConvex); collision_object.setWorldTransform(bt_xform); - GodotRestInfoContactResultCallback btQuery(&collision_object, r_info, &p_exclude); + GodotRestInfoContactResultCallback btQuery(&collision_object, r_info, &p_exclude, p_collide_with_bodies, p_collide_with_areas); btQuery.m_collisionFilterGroup = 0; btQuery.m_collisionFilterMask = p_collision_mask; btQuery.m_closestDistanceThreshold = 0; diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h index 95814d1fef7..517ec67ffa6 100644 --- a/modules/bullet/space_bullet.h +++ b/modules/bullet/space_bullet.h @@ -73,13 +73,13 @@ private: public: BulletPhysicsDirectSpaceState(SpaceBullet *p_space); - virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF); - virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_pick_ray = false); - virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, float p_margin, ShapeResult *r_results, int p_result_max, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF); - virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF, ShapeRestInfo *r_info = NULL); + virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); + virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_ray = false); + virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, float p_margin, ShapeResult *r_results, int p_result_max, const Set &p_exclude = Set(), 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 Transform &p_xform, const Vector3 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = NULL); /// Returns the list of contacts pairs in this order: Local contact, other body contact - virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, float p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF); - virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF); + virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, float p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set &p_exclude = Set(), 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 Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const; }; diff --git a/scene/3d/ray_cast.cpp b/scene/3d/ray_cast.cpp index 7f83e2c3ea0..e1897c0187e 100644 --- a/scene/3d/ray_cast.cpp +++ b/scene/3d/ray_cast.cpp @@ -49,6 +49,26 @@ 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; @@ -208,7 +228,7 @@ void RayCast::_update_raycast_state() { PhysicsDirectSpaceState::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; @@ -267,6 +287,12 @@ 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); @@ -295,6 +321,8 @@ void RayCast::_bind_methods() { 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"); } @@ -368,6 +396,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; } diff --git a/scene/3d/ray_cast.h b/scene/3d/ray_cast.h index 20cea807005..417cb884cc1 100644 --- a/scene/3d/ray_cast.h +++ b/scene/3d/ray_cast.h @@ -45,6 +45,8 @@ class RayCast : public Spatial { Vector3 collision_normal; Vector3 cast_to; + bool collide_with_bodies; + bool collide_with_areas; Set exclude; @@ -70,6 +72,12 @@ public: 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/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp index 9d6ec958b4d..a4ad19eba7f 100644 --- a/servers/physics/space_sw.cpp +++ b/servers/physics/space_sw.cpp @@ -39,7 +39,7 @@ _FORCE_INLINE_ static bool _can_collide_with(CollisionObjectSW *p_object, uint32 return p_object->get_collision_layer() & p_collision_mask; } -int PhysicsDirectSpaceStateSW::intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set &p_exclude, uint32_t p_collision_mask) { +int PhysicsDirectSpaceStateSW::intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { ERR_FAIL_COND_V(space->locked, false); int amount = space->broadphase->cull_point(p_point, space->intersection_query_results, SpaceSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); @@ -83,7 +83,7 @@ int PhysicsDirectSpaceStateSW::intersect_point(const Vector3 &p_point, ShapeResu return cc; } -bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set &p_exclude, uint32_t p_collision_mask, bool p_pick_ray) { +bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_ray) { ERR_FAIL_COND_V(space->locked, false); @@ -161,7 +161,7 @@ bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3 &p_from, const Vecto return true; } -int PhysicsDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set &p_exclude, uint32_t p_collision_mask) { +int PhysicsDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (p_result_max <= 0) return 0; @@ -212,7 +212,7 @@ int PhysicsDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transfo return cc; } -bool PhysicsDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set &p_exclude, uint32_t p_collision_mask, ShapeRestInfo *r_info) { +bool PhysicsDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) { ShapeSW *shape = static_cast(PhysicsServer::get_singleton())->shape_owner.get(p_shape); ERR_FAIL_COND_V(!shape, false); @@ -326,7 +326,7 @@ bool PhysicsDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform return true; } -bool PhysicsDirectSpaceStateSW::collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set &p_exclude, uint32_t p_collision_mask) { +bool PhysicsDirectSpaceStateSW::collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (p_result_max <= 0) return 0; @@ -405,7 +405,7 @@ static void _rest_cbk_result(const Vector3 &p_point_A, const Vector3 &p_point_B, rd->best_object = rd->object; rd->best_shape = rd->shape; } -bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set &p_exclude, uint32_t p_collision_mask) { +bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { ShapeSW *shape = static_cast(PhysicsServer::get_singleton())->shape_owner.get(p_shape); ERR_FAIL_COND_V(!shape, 0); diff --git a/servers/physics/space_sw.h b/servers/physics/space_sw.h index ed4b274d133..e7231df5322 100644 --- a/servers/physics/space_sw.h +++ b/servers/physics/space_sw.h @@ -48,12 +48,12 @@ class PhysicsDirectSpaceStateSW : public PhysicsDirectSpaceState { public: SpaceSW *space; - virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF); - virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_pick_ray = false); - virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF); - virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF, ShapeRestInfo *r_info = NULL); - virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF); - virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF); + virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); + virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_ray = false); + virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set &p_exclude = Set(), 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 Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = NULL); + virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set &p_exclude = Set(), 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 Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const; PhysicsDirectSpaceStateSW(); diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp index cda3856ecc2..94990e84958 100644 --- a/servers/physics_server.cpp +++ b/servers/physics_server.cpp @@ -29,7 +29,9 @@ /*************************************************************************/ #include "physics_server.h" + #include "core/project_settings.h" +#include "method_bind_ext.gen.inc" #include "print_string.h" PhysicsServer *PhysicsServer::singleton = NULL; @@ -262,14 +264,14 @@ Variant PhysicsDirectSpaceState::_intersect_shape(const RID& p_shape, const Tran } */ -Dictionary PhysicsDirectSpaceState::_intersect_ray(const Vector3 &p_from, const Vector3 &p_to, const Vector &p_exclude, uint32_t p_collision_mask) { +Dictionary PhysicsDirectSpaceState::_intersect_ray(const Vector3 &p_from, const Vector3 &p_to, const Vector &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { RayResult inters; Set 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_collision_mask); + bool res = intersect_ray(p_from, p_to, inters, exclude, p_collision_mask, p_collide_with_bodies, p_collide_with_areas); if (!res) return Dictionary(); @@ -285,11 +287,11 @@ Dictionary PhysicsDirectSpaceState::_intersect_ray(const Vector3 &p_from, const return d; } -Array PhysicsDirectSpaceState::_intersect_shape(const Ref &p_shape_query, int p_max_results) { +Array PhysicsDirectSpaceState::_intersect_shape(const Ref &p_shape_query, bool p_collide_with_bodies, bool p_collide_with_areas, int p_max_results) { Vector 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); + 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); Array ret; ret.resize(rc); for (int i = 0; i < rc; i++) { @@ -305,10 +307,10 @@ Array PhysicsDirectSpaceState::_intersect_shape(const Ref &p_shape_query, const Vector3 &p_motion) { +Array PhysicsDirectSpaceState::_cast_motion(const Ref &p_shape_query, const Vector3 &p_motion, bool p_collide_with_bodies, bool p_collide_with_areas) { 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); + 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); if (!res) return Array(); Array ret; @@ -317,12 +319,12 @@ Array PhysicsDirectSpaceState::_cast_motion(const Ref &p_shape_query, int p_max_results) { +Array PhysicsDirectSpaceState::_collide_shape(const Ref &p_shape_query, bool p_collide_with_bodies, bool p_collide_with_areas, int p_max_results) { Vector 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); + 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); if (!res) return Array(); Array r; @@ -331,11 +333,11 @@ Array PhysicsDirectSpaceState::_collide_shape(const Ref &p_shape_query) { +Dictionary PhysicsDirectSpaceState::_get_rest_info(const Ref &p_shape_query, bool p_collide_with_bodies, bool p_collide_with_areas) { 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); + 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); Dictionary r; if (!res) return r; @@ -358,11 +360,11 @@ void PhysicsDirectSpaceState::_bind_methods() { //ClassDB::bind_method(D_METHOD("intersect_ray","from","to","exclude","umask"),&PhysicsDirectSpaceState::_intersect_ray,DEFVAL(Array()),DEFVAL(0)); //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_layer"), &PhysicsDirectSpaceState::_intersect_ray, DEFVAL(Array()), DEFVAL(0x7FFFFFFF)); - 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); + 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)); } int PhysicsShapeQueryResult::get_result_count() const { diff --git a/servers/physics_server.h b/servers/physics_server.h index 85f9151c53c..3bd47a6601b 100644 --- a/servers/physics_server.h +++ b/servers/physics_server.h @@ -136,11 +136,11 @@ class PhysicsDirectSpaceState : public Object { GDCLASS(PhysicsDirectSpaceState, Object); private: - Dictionary _intersect_ray(const Vector3 &p_from, const Vector3 &p_to, const Vector &p_exclude = Vector(), uint32_t p_collision_mask = 0); - Array _intersect_shape(const Ref &p_shape_query, int p_max_results = 32); - Array _cast_motion(const Ref &p_shape_query, const Vector3 &p_motion); - Array _collide_shape(const Ref &p_shape_query, int p_max_results = 32); - Dictionary _get_rest_info(const Ref &p_shape_query); + Dictionary _intersect_ray(const Vector3 &p_from, const Vector3 &p_to, const Vector &p_exclude = Vector(), uint32_t p_collision_mask = 0, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); + Array _intersect_shape(const Ref &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 &p_shape_query, const Vector3 &p_motion, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); + Array _collide_shape(const Ref &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 &p_shape_query, bool p_collide_with_bodies = true, bool p_collide_with_areas = false); protected: static void _bind_methods(); @@ -154,7 +154,7 @@ public: int shape; }; - virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF) = 0; + virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; struct RayResult { @@ -166,9 +166,9 @@ public: int shape; }; - virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_pick_ray = false) = 0; + virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_ray = false) = 0; - virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, float p_margin, ShapeResult *r_results, int p_result_max, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF) = 0; + virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, float p_margin, ShapeResult *r_results, int p_result_max, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; struct ShapeRestInfo { @@ -180,11 +180,11 @@ public: Vector3 linear_velocity; //velocity at contact point }; - virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF, ShapeRestInfo *r_info = NULL) = 0; + virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = NULL) = 0; - virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, float p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF) = 0; + virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, float p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; - virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF) = 0; + virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const = 0;