diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 1cd6209e77d..6f833bb9557 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -2620,12 +2620,6 @@ If [code]true[/code], [RigidBody3D] nodes are allowed to go to sleep if their velocity is below the threshold defined in [member physics/jolt_physics_3d/simulation/sleep_velocity_threshold] for the duration set in [member physics/jolt_physics_3d/simulation/sleep_time_threshold]. This can improve physics simulation performance when there are non-moving [RigidBody3D] nodes, at the cost of some nodes possibly failing to wake up in certain scenarios. Consider disabling this temporarily to troubleshoot [RigidBody3D] nodes not moving when they should. - - If [code]true[/code], [Area3D] nodes are able to detect overlaps with [StaticBody3D] nodes. - [b]Note:[/b] Enabling this setting can come at a heavy CPU and memory cost if you allow many/large [Area3D] to overlap with complex static geometry, such as [ConcavePolygonShape3D] or [HeightMapShape3D]. It is strongly recommended that you set up your collision layers and masks in such a way that only a few small [Area3D] nodes can detect [StaticBody3D] nodes. - [b]Note:[/b] This also applies to overlaps with a [RigidBody3D] frozen with [constant RigidBody3D.FREEZE_MODE_STATIC]. - [b]Note:[/b] This is not needed to detect overlaps with [AnimatableBody3D], as it is a kinematic body, despite inheriting from [StaticBody3D]. - How much of the position error of a [RigidBody3D] to fix during a physics step, where [code]0.0[/code] is none and [code]1.0[/code] is the full amount. This affects things like how quickly bodies depenetrate. [b]Note:[/b] Setting this value too high can make [RigidBody3D] nodes unstable. diff --git a/modules/jolt_physics/jolt_project_settings.cpp b/modules/jolt_physics/jolt_project_settings.cpp index 5f5bd0f2fdc..8db7dd2fe9c 100644 --- a/modules/jolt_physics/jolt_project_settings.cpp +++ b/modules/jolt_physics/jolt_project_settings.cpp @@ -36,7 +36,6 @@ void JoltProjectSettings::register_settings() { GLOBAL_DEF(PropertyInfo(Variant::INT, "physics/jolt_physics_3d/simulation/velocity_steps", PROPERTY_HINT_RANGE, U"2,16,or_greater"), 10); GLOBAL_DEF(PropertyInfo(Variant::INT, "physics/jolt_physics_3d/simulation/position_steps", PROPERTY_HINT_RANGE, U"1,16,or_greater"), 2); GLOBAL_DEF(PropertyInfo(Variant::BOOL, "physics/jolt_physics_3d/simulation/use_enhanced_internal_edge_removal"), true); - GLOBAL_DEF(PropertyInfo(Variant::BOOL, "physics/jolt_physics_3d/simulation/areas_detect_static_bodies"), false); GLOBAL_DEF(PropertyInfo(Variant::BOOL, "physics/jolt_physics_3d/simulation/generate_all_kinematic_contacts"), false); GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/jolt_physics_3d/simulation/penetration_slop", PROPERTY_HINT_RANGE, U"0,1,0.00001,or_greater,suffix:m"), 0.02f); GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/jolt_physics_3d/simulation/speculative_contact_distance", PROPERTY_HINT_RANGE, U"0,1,0.00001,or_greater,suffix:m"), 0.02f); @@ -81,7 +80,6 @@ void JoltProjectSettings::read_settings() { simulation_velocity_steps = GLOBAL_GET("physics/jolt_physics_3d/simulation/velocity_steps"); simulation_position_steps = GLOBAL_GET("physics/jolt_physics_3d/simulation/position_steps"); use_enhanced_internal_edge_removal_for_bodies = GLOBAL_GET("physics/jolt_physics_3d/simulation/use_enhanced_internal_edge_removal"); - areas_detect_static_bodies = GLOBAL_GET("physics/jolt_physics_3d/simulation/areas_detect_static_bodies"); generate_all_kinematic_contacts = GLOBAL_GET("physics/jolt_physics_3d/simulation/generate_all_kinematic_contacts"); penetration_slop = GLOBAL_GET("physics/jolt_physics_3d/simulation/penetration_slop"); speculative_contact_distance = GLOBAL_GET("physics/jolt_physics_3d/simulation/speculative_contact_distance"); diff --git a/modules/jolt_physics/jolt_project_settings.h b/modules/jolt_physics/jolt_project_settings.h index afda6242657..4c4efbec9ba 100644 --- a/modules/jolt_physics/jolt_project_settings.h +++ b/modules/jolt_physics/jolt_project_settings.h @@ -42,7 +42,6 @@ public: inline static int simulation_velocity_steps; inline static int simulation_position_steps; inline static bool use_enhanced_internal_edge_removal_for_bodies; - inline static bool areas_detect_static_bodies; inline static bool generate_all_kinematic_contacts; inline static float penetration_slop; inline static float speculative_contact_distance; diff --git a/modules/jolt_physics/objects/jolt_area_3d.cpp b/modules/jolt_physics/objects/jolt_area_3d.cpp index 1c89c93a61a..c0326e7fbf9 100644 --- a/modules/jolt_physics/objects/jolt_area_3d.cpp +++ b/modules/jolt_physics/objects/jolt_area_3d.cpp @@ -72,15 +72,12 @@ void JoltArea3D::_add_to_space() { jolt_settings->mCollisionGroup = JPH::CollisionGroup(nullptr, group_id, sub_group_id); jolt_settings->mMotionType = _get_motion_type(); jolt_settings->mIsSensor = true; + jolt_settings->mCollideKinematicVsNonDynamic = true; jolt_settings->mUseManifoldReduction = false; jolt_settings->mOverrideMassProperties = JPH::EOverrideMassProperties::MassAndInertiaProvided; jolt_settings->mMassPropertiesOverride.mMass = 1.0f; jolt_settings->mMassPropertiesOverride.mInertia = JPH::Mat44::sIdentity(); - if (JoltProjectSettings::areas_detect_static_bodies) { - jolt_settings->mCollideKinematicVsNonDynamic = true; - } - jolt_settings->SetShape(jolt_shape); JPH::Body *new_jolt_body = space->add_rigid_body(*this, *jolt_settings, _should_sleep()); diff --git a/modules/jolt_physics/spaces/jolt_layers.cpp b/modules/jolt_physics/spaces/jolt_layers.cpp index d591dce59de..14c3afff1dd 100644 --- a/modules/jolt_physics/spaces/jolt_layers.cpp +++ b/modules/jolt_physics/spaces/jolt_layers.cpp @@ -52,28 +52,25 @@ public: using namespace JoltBroadPhaseLayer; allow_collision(BODY_STATIC, BODY_DYNAMIC); + allow_collision(BODY_STATIC, AREA_DETECTABLE); + allow_collision(BODY_STATIC, AREA_UNDETECTABLE); allow_collision(BODY_STATIC_BIG, BODY_DYNAMIC); + allow_collision(BODY_STATIC_BIG, AREA_DETECTABLE); + allow_collision(BODY_STATIC_BIG, AREA_UNDETECTABLE); allow_collision(BODY_DYNAMIC, BODY_STATIC); allow_collision(BODY_DYNAMIC, BODY_STATIC_BIG); allow_collision(BODY_DYNAMIC, BODY_DYNAMIC); allow_collision(BODY_DYNAMIC, AREA_DETECTABLE); allow_collision(BODY_DYNAMIC, AREA_UNDETECTABLE); allow_collision(AREA_DETECTABLE, BODY_DYNAMIC); + allow_collision(AREA_DETECTABLE, BODY_STATIC); + allow_collision(AREA_DETECTABLE, BODY_STATIC_BIG); allow_collision(AREA_DETECTABLE, AREA_DETECTABLE); allow_collision(AREA_DETECTABLE, AREA_UNDETECTABLE); allow_collision(AREA_UNDETECTABLE, BODY_DYNAMIC); + allow_collision(AREA_UNDETECTABLE, BODY_STATIC); + allow_collision(AREA_UNDETECTABLE, BODY_STATIC_BIG); allow_collision(AREA_UNDETECTABLE, AREA_DETECTABLE); - - if (JoltProjectSettings::areas_detect_static_bodies) { - allow_collision(BODY_STATIC, AREA_DETECTABLE); - allow_collision(BODY_STATIC, AREA_UNDETECTABLE); - allow_collision(BODY_STATIC_BIG, AREA_DETECTABLE); - allow_collision(BODY_STATIC_BIG, AREA_UNDETECTABLE); - allow_collision(AREA_DETECTABLE, BODY_STATIC); - allow_collision(AREA_DETECTABLE, BODY_STATIC_BIG); - allow_collision(AREA_UNDETECTABLE, BODY_STATIC); - allow_collision(AREA_UNDETECTABLE, BODY_STATIC_BIG); - } } void allow_collision(UnderlyingType p_layer1, UnderlyingType p_layer2) { masks[p_layer1] |= uint8_t(1U << p_layer2); } diff --git a/modules/jolt_physics/spaces/jolt_space_3d.cpp b/modules/jolt_physics/spaces/jolt_space_3d.cpp index 5d73b0fd1e1..cfe197cb094 100644 --- a/modules/jolt_physics/spaces/jolt_space_3d.cpp +++ b/modules/jolt_physics/spaces/jolt_space_3d.cpp @@ -48,6 +48,8 @@ #include "core/string/print_string.h" #include "core/variant/variant_utility.h" +#include "Jolt/Physics/Collision/CollideShapeVsShapePerLeaf.h" +#include "Jolt/Physics/Collision/CollisionCollectorImpl.h" #include "Jolt/Physics/PhysicsScene.h" namespace { @@ -121,6 +123,18 @@ JoltSpace3D::JoltSpace3D(JPH::JobSystem *p_job_system) : physics_system->SetContactListener(contact_listener); physics_system->SetSoftBodyContactListener(contact_listener); + physics_system->SetSimCollideBodyVsBody([](const JPH::Body &p_body1, const JPH::Body &p_body2, JPH::Mat44Arg p_transform_com1, JPH::Mat44Arg p_transform_com2, JPH::CollideShapeSettings &p_collide_shape_settings, JPH::CollideShapeCollector &p_collector, const JPH::ShapeFilter &p_shape_filter) { + if (p_body1.IsSensor() || p_body2.IsSensor()) { + JPH::CollideShapeSettings new_collide_shape_settings = p_collide_shape_settings; + // Since we're breaking the sensor down into leaf shapes we'll end up stripping away our `JoltCustomDoubleSidedShape` decorator shape and thus any back-face collision, so we simply force-enable it like this rather than going through the trouble of reapplying the decorator. + new_collide_shape_settings.mBackFaceMode = JPH::EBackFaceMode::CollideWithBackFaces; + JPH::SubShapeIDCreator part1, part2; + JPH::CollideShapeVsShapePerLeaf>(p_body1.GetShape(), p_body2.GetShape(), JPH::Vec3::sOne(), JPH::Vec3::sOne(), p_transform_com1, p_transform_com2, part1, part2, new_collide_shape_settings, p_collector, p_shape_filter); + } else { + JPH::PhysicsSystem::sDefaultSimCollideBodyVsBody(p_body1, p_body2, p_transform_com1, p_transform_com2, p_collide_shape_settings, p_collector, p_shape_filter); + } + }); + physics_system->SetCombineFriction([](const JPH::Body &p_body1, const JPH::SubShapeID &p_sub_shape_id1, const JPH::Body &p_body2, const JPH::SubShapeID &p_sub_shape_id2) { return Math::abs(MIN(p_body1.GetFriction(), p_body2.GetFriction())); });