diff --git a/doc/classes/PhysicalBone3D.xml b/doc/classes/PhysicalBone3D.xml
index b69fb7050e7f..f363a9bfa8a2 100644
--- a/doc/classes/PhysicalBone3D.xml
+++ b/doc/classes/PhysicalBone3D.xml
@@ -74,6 +74,9 @@
This is multiplied by the global 3D gravity setting found in [b]Project > Project Settings > Physics > 3d[/b] to produce the body's gravity. For example, a value of 1 will be normal gravity, 2 will apply double gravity, and 0.5 will apply half gravity to this object.
+
+ If [code]true[/code], the bone is not able to collide with the parent bone.
+
Sets the joint's transform.
diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp
index 71ab96f6e7e4..dd2a51b4baaa 100644
--- a/scene/3d/physics_body_3d.cpp
+++ b/scene/3d/physics_body_3d.cpp
@@ -2964,6 +2964,8 @@ void PhysicalBone3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_joint_offset"), &PhysicalBone3D::get_joint_offset);
ClassDB::bind_method(D_METHOD("set_joint_rotation", "euler"), &PhysicalBone3D::set_joint_rotation);
ClassDB::bind_method(D_METHOD("get_joint_rotation"), &PhysicalBone3D::get_joint_rotation);
+ ClassDB::bind_method(D_METHOD("set_joint_exclude_nodes_from_collision", "exclude_nodes_from_collision"), &PhysicalBone3D::set_joint_exclude_nodes_from_collision);
+ ClassDB::bind_method(D_METHOD("get_joint_exclude_nodes_from_collision"), &PhysicalBone3D::get_joint_exclude_nodes_from_collision);
ClassDB::bind_method(D_METHOD("set_body_offset", "offset"), &PhysicalBone3D::set_body_offset);
ClassDB::bind_method(D_METHOD("get_body_offset"), &PhysicalBone3D::get_body_offset);
@@ -3016,6 +3018,7 @@ void PhysicalBone3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "joint_type", PROPERTY_HINT_ENUM, "None,PinJoint,ConeJoint,HingeJoint,SliderJoint,6DOFJoint"), "set_joint_type", "get_joint_type");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "joint_offset", PROPERTY_HINT_NONE, "suffix:m"), "set_joint_offset", "get_joint_offset");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation", PROPERTY_HINT_RANGE, "-360,360,0.01,or_less,or_greater,radians"), "set_joint_rotation", "get_joint_rotation");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "joint_exclude_nodes_from_collision"), "set_joint_exclude_nodes_from_collision", "get_joint_exclude_nodes_from_collision");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "body_offset", PROPERTY_HINT_NONE, "suffix:m"), "set_body_offset", "get_body_offset");
@@ -3093,6 +3096,7 @@ void PhysicalBone3D::_reload_joint() {
PhysicsServer3D::get_singleton()->pin_joint_set_param(joint, PhysicsServer3D::PIN_JOINT_BIAS, pjd->bias);
PhysicsServer3D::get_singleton()->pin_joint_set_param(joint, PhysicsServer3D::PIN_JOINT_DAMPING, pjd->damping);
PhysicsServer3D::get_singleton()->pin_joint_set_param(joint, PhysicsServer3D::PIN_JOINT_IMPULSE_CLAMP, pjd->impulse_clamp);
+ PhysicsServer3D::get_singleton()->joint_disable_collisions_between_bodies(joint, joint_exclude_nodes_from_collision);
} break;
case JOINT_TYPE_CONE: {
@@ -3103,6 +3107,7 @@ void PhysicalBone3D::_reload_joint() {
PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(joint, PhysicsServer3D::CONE_TWIST_JOINT_BIAS, cjd->bias);
PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(joint, PhysicsServer3D::CONE_TWIST_JOINT_SOFTNESS, cjd->softness);
PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(joint, PhysicsServer3D::CONE_TWIST_JOINT_RELAXATION, cjd->relaxation);
+ PhysicsServer3D::get_singleton()->joint_disable_collisions_between_bodies(joint, joint_exclude_nodes_from_collision);
} break;
case JOINT_TYPE_HINGE: {
@@ -3114,6 +3119,7 @@ void PhysicalBone3D::_reload_joint() {
PhysicsServer3D::get_singleton()->hinge_joint_set_param(joint, PhysicsServer3D::HINGE_JOINT_LIMIT_BIAS, hjd->angular_limit_bias);
PhysicsServer3D::get_singleton()->hinge_joint_set_param(joint, PhysicsServer3D::HINGE_JOINT_LIMIT_SOFTNESS, hjd->angular_limit_softness);
PhysicsServer3D::get_singleton()->hinge_joint_set_param(joint, PhysicsServer3D::HINGE_JOINT_LIMIT_RELAXATION, hjd->angular_limit_relaxation);
+ PhysicsServer3D::get_singleton()->joint_disable_collisions_between_bodies(joint, joint_exclude_nodes_from_collision);
} break;
case JOINT_TYPE_SLIDER: {
@@ -3129,6 +3135,7 @@ void PhysicalBone3D::_reload_joint() {
PhysicsServer3D::get_singleton()->slider_joint_set_param(joint, PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS, sjd->angular_limit_softness);
PhysicsServer3D::get_singleton()->slider_joint_set_param(joint, PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS, sjd->angular_limit_softness);
PhysicsServer3D::get_singleton()->slider_joint_set_param(joint, PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING, sjd->angular_limit_damping);
+ PhysicsServer3D::get_singleton()->joint_disable_collisions_between_bodies(joint, joint_exclude_nodes_from_collision);
} break;
case JOINT_TYPE_6DOF: {
@@ -3156,6 +3163,7 @@ void PhysicalBone3D::_reload_joint() {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(joint, static_cast(axis), PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS, g6dofjd->axis_data[axis].angular_spring_stiffness);
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(joint, static_cast(axis), PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_DAMPING, g6dofjd->axis_data[axis].angular_spring_damping);
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(joint, static_cast(axis), PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT, g6dofjd->axis_data[axis].angular_equilibrium_point);
+ PhysicsServer3D::get_singleton()->joint_disable_collisions_between_bodies(joint, joint_exclude_nodes_from_collision);
}
} break;
@@ -3251,6 +3259,18 @@ Vector3 PhysicalBone3D::get_joint_rotation() const {
return joint_offset.basis.get_euler_normalized();
}
+void PhysicalBone3D::set_joint_exclude_nodes_from_collision(bool p_exclude_nodes_from_collision) {
+ if (joint_exclude_nodes_from_collision == p_exclude_nodes_from_collision) {
+ return;
+ }
+ joint_exclude_nodes_from_collision = p_exclude_nodes_from_collision;
+ _reload_joint();
+}
+
+bool PhysicalBone3D::get_joint_exclude_nodes_from_collision() const {
+ return joint_exclude_nodes_from_collision;
+}
+
const Transform3D &PhysicalBone3D::get_body_offset() const {
return body_offset;
}
diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h
index 9798fc48450c..97187337756b 100644
--- a/scene/3d/physics_body_3d.h
+++ b/scene/3d/physics_body_3d.h
@@ -656,6 +656,7 @@ class PhysicalBone3D : public PhysicsBody3D {
JointData *joint_data = nullptr;
Transform3D joint_offset;
+ bool joint_exclude_nodes_from_collision = true;
RID joint;
Skeleton3D *parent_skeleton = nullptr;
@@ -738,6 +739,9 @@ class PhysicalBone3D : public PhysicsBody3D {
void set_body_offset(const Transform3D &p_offset);
const Transform3D &get_body_offset() const;
+ void set_joint_exclude_nodes_from_collision(bool p_exclude_nodes_from_collision);
+ bool get_joint_exclude_nodes_from_collision() const;
+
void set_simulate_physics(bool p_simulate);
bool get_simulate_physics();
bool is_simulating_physics();