diff --git a/doc/classes/Joint2D.xml b/doc/classes/Joint2D.xml
index 0099c76d08d7..02854adf8a01 100644
--- a/doc/classes/Joint2D.xml
+++ b/doc/classes/Joint2D.xml
@@ -24,6 +24,9 @@
If [code]true[/code], the two bodies bound together do not collide with each other.
+
+ Defines the behavior in physics when [member Node.process_mode] is set to [constant Node.PROCESS_MODE_DISABLED]. See [enum DisableMode] for more details about the different modes.
+
Path to the first body (A) attached to the joint. The node must inherit [PhysicsBody2D].
@@ -31,4 +34,13 @@
Path to the second body (B) attached to the joint. The node must inherit [PhysicsBody2D].
+
+
+ When [member Node.process_mode] is set to [constant Node.PROCESS_MODE_DISABLED], remove from the physics simulation to stop all physics interactions with this [Joint2D].
+ Automatically re-added to the physics simulation when the [Node] is processed again with initial transforms for bodies.
+
+
+ When [member Node.process_mode] is set to [constant Node.PROCESS_MODE_DISABLED], do not affect the physics simulation.
+
+
diff --git a/doc/classes/Joint3D.xml b/doc/classes/Joint3D.xml
index 950129806a2e..7ec9ca9cbd53 100644
--- a/doc/classes/Joint3D.xml
+++ b/doc/classes/Joint3D.xml
@@ -18,6 +18,9 @@
+
+ Defines the behavior in physics when [member Node.process_mode] is set to [constant Node.PROCESS_MODE_DISABLED]. See [enum DisableMode] for more details about the different modes.
+
If [code]true[/code], the two bodies bound together do not collide with each other.
@@ -33,4 +36,13 @@
The priority used to define which solver is executed first for multiple joints. The lower the value, the higher the priority.
+
+
+ When [member Node.process_mode] is set to [constant Node.PROCESS_MODE_DISABLED], remove from the physics simulation to stop all physics interactions with this [Joint3D].
+ Automatically re-added to the physics simulation when the [Node] is processed again with initial transforms for bodies.
+
+
+ When [member Node.process_mode] is set to [constant Node.PROCESS_MODE_DISABLED], do not affect the physics simulation.
+
+
diff --git a/doc/classes/PhysicsServer2D.xml b/doc/classes/PhysicsServer2D.xml
index bd960e3da517..d7447d22d244 100644
--- a/doc/classes/PhysicsServer2D.xml
+++ b/doc/classes/PhysicsServer2D.xml
@@ -790,6 +790,13 @@
Sets whether the bodies attached to the [Joint2D] will collide with each other.
+
+
+
+
+ Gets joint enable state.
+
+
@@ -845,6 +852,14 @@
Makes the joint a pin joint. If [param body_b] is an empty [RID], then [param body_a] is pinned to the point [param anchor] (given in global coordinates); otherwise, [param body_a] is pinned to [param body_b] at the point [param anchor] (given in global coordinates). To set the parameters which are specific to the pin joint, see [method pin_joint_set_param].
+
+
+
+
+
+ Enable or disable a joint.
+
+
diff --git a/doc/classes/PhysicsServer2DExtension.xml b/doc/classes/PhysicsServer2DExtension.xml
index 07c65915c6f0..fd592304d344 100644
--- a/doc/classes/PhysicsServer2DExtension.xml
+++ b/doc/classes/PhysicsServer2DExtension.xml
@@ -840,6 +840,13 @@
Overridable version of [method PhysicsServer2D.joint_disable_collisions_between_bodies].
+
+
+
+
+ Overridable version of [method PhysicsServer2D.joint_is_enabled].
+
+
@@ -895,6 +902,14 @@
Overridable version of [method PhysicsServer2D.joint_make_pin].
+
+
+
+
+
+ Overridable version of [method PhysicsServer2D.joint_set_enabled].
+
+
diff --git a/doc/classes/PhysicsServer3D.xml b/doc/classes/PhysicsServer3D.xml
index f87d6342c79d..4f12bf2a928a 100644
--- a/doc/classes/PhysicsServer3D.xml
+++ b/doc/classes/PhysicsServer3D.xml
@@ -855,6 +855,13 @@
Sets whether the bodies attached to the [Joint3D] will collide with each other.
+
+
+
+
+ Gets the joint enabled state.
+
+
@@ -927,6 +934,14 @@
+
+
+
+
+
+ Enable or disable the joint.
+
+
diff --git a/doc/classes/PhysicsServer3DExtension.xml b/doc/classes/PhysicsServer3DExtension.xml
index e58a7ff9a8aa..7afc524ce28e 100644
--- a/doc/classes/PhysicsServer3DExtension.xml
+++ b/doc/classes/PhysicsServer3DExtension.xml
@@ -783,6 +783,12 @@
+
+
+
+
+
+
@@ -863,6 +869,13 @@
+
+
+
+
+
+
+
diff --git a/modules/godot_physics_2d/godot_joints_2d.cpp b/modules/godot_physics_2d/godot_joints_2d.cpp
index 5c76eb9dadb6..868a2de2c3d0 100644
--- a/modules/godot_physics_2d/godot_joints_2d.cpp
+++ b/modules/godot_physics_2d/godot_joints_2d.cpp
@@ -61,6 +61,7 @@ void GodotJoint2D::copy_settings_from(GodotJoint2D *p_joint) {
set_bias(p_joint->get_bias());
set_max_bias(p_joint->get_max_bias());
disable_collisions_between_bodies(p_joint->is_disabled_collisions_between_bodies());
+ set_enabled(p_joint->is_enabled());
}
static inline real_t k_scalar(GodotBody2D *a, GodotBody2D *b, const Vector2 &rA, const Vector2 &rB, const Vector2 &n) {
@@ -315,15 +316,14 @@ bool GodotPinJoint2D::get_flag(PhysicsServer2D::PinJointFlag p_flag) const {
}
GodotPinJoint2D::GodotPinJoint2D(const Vector2 &p_pos, GodotBody2D *p_body_a, GodotBody2D *p_body_b) :
- GodotJoint2D(_arr, p_body_b ? 2 : 1) {
+ GodotJoint2D(p_body_b ? 2 : 1) {
A = p_body_a;
B = p_body_b;
anchor_A = p_body_a->get_inv_transform().xform(p_pos);
anchor_B = p_body_b ? p_body_b->get_inv_transform().xform(p_pos) : p_pos;
- p_body_a->add_constraint(this, 0);
+ add_constraint_to_bodies();
if (p_body_b) {
- p_body_b->add_constraint(this, 1);
initial_angle = A->get_transform().get_origin().angle_to_point(B->get_transform().get_origin());
}
}
@@ -471,7 +471,7 @@ void GodotGrooveJoint2D::solve(real_t p_step) {
}
GodotGrooveJoint2D::GodotGrooveJoint2D(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, GodotBody2D *p_body_a, GodotBody2D *p_body_b) :
- GodotJoint2D(_arr, 2) {
+ GodotJoint2D(2) {
A = p_body_a;
B = p_body_b;
@@ -480,8 +480,7 @@ GodotGrooveJoint2D::GodotGrooveJoint2D(const Vector2 &p_a_groove1, const Vector2
B_anchor = B->get_inv_transform().xform(p_b_anchor);
A_groove_normal = -(A_groove_2 - A_groove_1).normalized().orthogonal();
- A->add_constraint(this, 0);
- B->add_constraint(this, 1);
+ add_constraint_to_bodies();
}
//////////////////////////////////////////////
@@ -582,14 +581,12 @@ real_t GodotDampedSpringJoint2D::get_param(PhysicsServer2D::DampedSpringParam p_
}
GodotDampedSpringJoint2D::GodotDampedSpringJoint2D(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, GodotBody2D *p_body_a, GodotBody2D *p_body_b) :
- GodotJoint2D(_arr, 2) {
+ GodotJoint2D(2) {
A = p_body_a;
B = p_body_b;
anchor_A = A->get_inv_transform().xform(p_anchor_a);
anchor_B = B->get_inv_transform().xform(p_anchor_b);
rest_length = p_anchor_a.distance_to(p_anchor_b);
-
- A->add_constraint(this, 0);
- B->add_constraint(this, 1);
+ add_constraint_to_bodies();
}
diff --git a/modules/godot_physics_2d/godot_joints_2d.h b/modules/godot_physics_2d/godot_joints_2d.h
index 54884e112aec..edefb89f8721 100644
--- a/modules/godot_physics_2d/godot_joints_2d.h
+++ b/modules/godot_physics_2d/godot_joints_2d.h
@@ -38,11 +38,39 @@ class GodotJoint2D : public GodotConstraint2D {
real_t bias = 0;
real_t max_bias = 3.40282e+38;
real_t max_force = 3.40282e+38;
+ bool enabled = true;
protected:
bool dynamic_A = false;
bool dynamic_B = false;
+ union {
+ struct {
+ GodotBody2D *A;
+ GodotBody2D *B;
+ };
+
+ GodotBody2D *_arr[2] = { nullptr, nullptr };
+ };
+
+ void add_constraint_to_bodies() {
+ if (A) {
+ A->add_constraint(this, 0);
+ }
+ if (B) {
+ B->add_constraint(this, 1);
+ }
+ }
+
+ void remove_constraint_from_bodies() {
+ for (int i = 0; i < get_body_count(); i++) {
+ GodotBody2D *body = get_body_ptr()[i];
+ if (body) {
+ body->remove_constraint(this, i);
+ }
+ }
+ }
+
public:
_FORCE_INLINE_ void set_max_force(real_t p_force) { max_force = p_force; }
_FORCE_INLINE_ real_t get_max_force() const { return max_force; }
@@ -53,6 +81,16 @@ class GodotJoint2D : public GodotConstraint2D {
_FORCE_INLINE_ void set_max_bias(real_t p_bias) { max_bias = p_bias; }
_FORCE_INLINE_ real_t get_max_bias() const { return max_bias; }
+ _FORCE_INLINE_ void set_enabled(bool p_enabled) {
+ enabled = p_enabled;
+ if (enabled) {
+ add_constraint_to_bodies();
+ } else {
+ remove_constraint_from_bodies();
+ }
+ }
+ _FORCE_INLINE_ bool is_enabled() const { return enabled; }
+
virtual bool setup(real_t p_step) override { return false; }
virtual bool pre_solve(real_t p_step) override { return false; }
virtual void solve(real_t p_step) override {}
@@ -60,29 +98,15 @@ class GodotJoint2D : public GodotConstraint2D {
void copy_settings_from(GodotJoint2D *p_joint);
virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_TYPE_MAX; }
- GodotJoint2D(GodotBody2D **p_body_ptr = nullptr, int p_body_count = 0) :
- GodotConstraint2D(p_body_ptr, p_body_count) {}
+ GodotJoint2D(int p_body_count = 0) :
+ GodotConstraint2D(_arr, p_body_count) {}
virtual ~GodotJoint2D() {
- for (int i = 0; i < get_body_count(); i++) {
- GodotBody2D *body = get_body_ptr()[i];
- if (body) {
- body->remove_constraint(this, i);
- }
- }
- }
+ remove_constraint_from_bodies();
+ };
};
class GodotPinJoint2D : public GodotJoint2D {
- union {
- struct {
- GodotBody2D *A;
- GodotBody2D *B;
- };
-
- GodotBody2D *_arr[2] = { nullptr, nullptr };
- };
-
Transform2D M;
Vector2 rA, rB;
Vector2 anchor_A;
@@ -119,15 +143,6 @@ class GodotPinJoint2D : public GodotJoint2D {
};
class GodotGrooveJoint2D : public GodotJoint2D {
- union {
- struct {
- GodotBody2D *A;
- GodotBody2D *B;
- };
-
- GodotBody2D *_arr[2] = { nullptr, nullptr };
- };
-
Vector2 A_groove_1;
Vector2 A_groove_2;
Vector2 A_groove_normal;
@@ -153,15 +168,6 @@ class GodotGrooveJoint2D : public GodotJoint2D {
};
class GodotDampedSpringJoint2D : public GodotJoint2D {
- union {
- struct {
- GodotBody2D *A;
- GodotBody2D *B;
- };
-
- GodotBody2D *_arr[2] = { nullptr, nullptr };
- };
-
Vector2 anchor_A;
Vector2 anchor_B;
diff --git a/modules/godot_physics_2d/godot_physics_server_2d.cpp b/modules/godot_physics_2d/godot_physics_server_2d.cpp
index 71d1d3b6b18c..4c1709a5f01f 100644
--- a/modules/godot_physics_2d/godot_physics_server_2d.cpp
+++ b/modules/godot_physics_2d/godot_physics_server_2d.cpp
@@ -1042,6 +1042,20 @@ void GodotPhysicsServer2D::joint_clear(RID p_joint) {
}
}
+void GodotPhysicsServer2D::joint_set_enabled(RID p_joint, bool p_enabled) {
+ GodotJoint2D *joint = joint_owner.get_or_null(p_joint);
+ ERR_FAIL_NULL(joint);
+
+ joint->set_enabled(p_enabled);
+}
+
+bool GodotPhysicsServer2D::joint_is_enabled(RID p_joint) const {
+ const GodotJoint2D *joint = joint_owner.get_or_null(p_joint);
+ ERR_FAIL_NULL_V(joint, false);
+
+ return joint->is_enabled();
+}
+
void GodotPhysicsServer2D::joint_set_param(RID p_joint, JointParam p_param, real_t p_value) {
GodotJoint2D *joint = joint_owner.get_or_null(p_joint);
ERR_FAIL_NULL(joint);
diff --git a/modules/godot_physics_2d/godot_physics_server_2d.h b/modules/godot_physics_2d/godot_physics_server_2d.h
index 991cf67c951f..bf5426918669 100644
--- a/modules/godot_physics_2d/godot_physics_server_2d.h
+++ b/modules/godot_physics_2d/godot_physics_server_2d.h
@@ -265,6 +265,9 @@ class GodotPhysicsServer2D : public PhysicsServer2D {
virtual void joint_clear(RID p_joint) override;
+ virtual void joint_set_enabled(RID p_joint, bool p_enabled) override;
+ virtual bool joint_is_enabled(RID p_joint) const override;
+
virtual void joint_set_param(RID p_joint, JointParam p_param, real_t p_value) override;
virtual real_t joint_get_param(RID p_joint, JointParam p_param) const override;
diff --git a/modules/godot_physics_3d/godot_joint_3d.h b/modules/godot_physics_3d/godot_joint_3d.h
index 3207723cb48f..8c59b30fc465 100644
--- a/modules/godot_physics_3d/godot_joint_3d.h
+++ b/modules/godot_physics_3d/godot_joint_3d.h
@@ -36,6 +36,32 @@
class GodotJoint3D : public GodotConstraint3D {
protected:
+ union {
+ struct {
+ GodotBody3D *A;
+ GodotBody3D *B;
+ };
+
+ GodotBody3D *_arr[2] = { nullptr, nullptr };
+ };
+ bool enabled = true;
+ void remove_constraint_from_bodies() {
+ for (int i = 0; i < get_body_count(); i++) {
+ GodotBody3D *body = get_body_ptr()[i];
+ if (body) {
+ body->remove_constraint(this);
+ }
+ }
+ }
+
+ void add_constraint_to_bodies() {
+ if (A) {
+ A->add_constraint(this, 0);
+ }
+ if (B) {
+ B->add_constraint(this, 1);
+ }
+ }
bool dynamic_A = false;
bool dynamic_B = false;
@@ -73,6 +99,16 @@ class GodotJoint3D : public GodotConstraint3D {
}
public:
+ _FORCE_INLINE_ void set_enabled(bool p_enabled) {
+ enabled = p_enabled;
+ if (enabled) {
+ add_constraint_to_bodies();
+ } else {
+ remove_constraint_from_bodies();
+ }
+ }
+ _FORCE_INLINE_ bool is_enabled() const { return eabled; }
+
virtual bool setup(real_t p_step) override { return false; }
virtual bool pre_solve(real_t p_step) override { return true; }
virtual void solve(real_t p_step) override {}
@@ -81,20 +117,16 @@ class GodotJoint3D : public GodotConstraint3D {
set_self(p_joint->get_self());
set_priority(p_joint->get_priority());
disable_collisions_between_bodies(p_joint->is_disabled_collisions_between_bodies());
+ set_enabled(p_joint->is_enabled());
}
virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_MAX; }
- _FORCE_INLINE_ GodotJoint3D(GodotBody3D **p_body_ptr = nullptr, int p_body_count = 0) :
- GodotConstraint3D(p_body_ptr, p_body_count) {
+ _FORCE_INLINE_ GodotJoint3D() :
+ GodotConstraint3D(_arr, 2) {
}
virtual ~GodotJoint3D() {
- for (int i = 0; i < get_body_count(); i++) {
- GodotBody3D *body = get_body_ptr()[i];
- if (body) {
- body->remove_constraint(this);
- }
- }
+ remove_constraint_from_bodies();
}
};
diff --git a/modules/godot_physics_3d/godot_physics_server_3d.cpp b/modules/godot_physics_3d/godot_physics_server_3d.cpp
index 43f8d2658dc9..ddc09a603fcf 100644
--- a/modules/godot_physics_3d/godot_physics_server_3d.cpp
+++ b/modules/godot_physics_3d/godot_physics_server_3d.cpp
@@ -1220,6 +1220,20 @@ void GodotPhysicsServer3D::joint_clear(RID p_joint) {
}
}
+void GodotPhysicsServer3D::joint_set_enabled(RID p_joint, bool p_enabled) {
+ GodotJoint3D *joint = joint_owner.get_or_null(p_joint);
+ ERR_FAIL_NULL(joint);
+
+ joint->set_enabled(p_enabled);
+}
+
+bool GodotPhysicsServer3D::joint_is_enabled(RID p_joint) const {
+ const GodotJoint3D *joint = joint_owner.get_or_null(p_joint);
+ ERR_FAIL_NULL_V(joint, false);
+
+ return joint->is_enabled();
+}
+
void GodotPhysicsServer3D::joint_make_pin(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) {
GodotBody3D *body_A = body_owner.get_or_null(p_body_A);
ERR_FAIL_NULL(body_A);
diff --git a/modules/godot_physics_3d/godot_physics_server_3d.h b/modules/godot_physics_3d/godot_physics_server_3d.h
index 040e673dcd82..b3dc6f022b5b 100644
--- a/modules/godot_physics_3d/godot_physics_server_3d.h
+++ b/modules/godot_physics_3d/godot_physics_server_3d.h
@@ -316,6 +316,9 @@ class GodotPhysicsServer3D : public PhysicsServer3D {
virtual void joint_clear(RID p_joint) override; //resets type
+ virtual void joint_set_enabled(RID p_joint, bool p_enabled) override;
+ virtual bool joint_is_enabled(RID p_joint) const override;
+
virtual void joint_make_pin(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) override;
virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) override;
diff --git a/modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.cpp b/modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.cpp
index 409142278987..d529268b2233 100644
--- a/modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.cpp
+++ b/modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.cpp
@@ -52,15 +52,14 @@ Written by: Marcus Hennix
#include "godot_cone_twist_joint_3d.h"
GodotConeTwistJoint3D::GodotConeTwistJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Transform3D &rbAFrame, const Transform3D &rbBFrame) :
- GodotJoint3D(_arr, 2) {
+ GodotJoint3D() {
A = rbA;
B = rbB;
m_rbAFrame = rbAFrame;
m_rbBFrame = rbBFrame;
- A->add_constraint(this, 0);
- B->add_constraint(this, 1);
+ add_constraint_to_bodies();
}
bool GodotConeTwistJoint3D::setup(real_t p_timestep) {
diff --git a/modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.h b/modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.h
index f3b683a8f38a..afcf802084b3 100644
--- a/modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.h
+++ b/modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.h
@@ -60,16 +60,6 @@ class GodotConeTwistJoint3D : public GodotJoint3D {
#ifdef IN_PARALLELL_SOLVER
public:
#endif
-
- union {
- struct {
- GodotBody3D *A;
- GodotBody3D *B;
- };
-
- GodotBody3D *_arr[2] = { nullptr, nullptr };
- };
-
GodotJacobianEntry3D m_jac[3] = {}; //3 orthogonal linear constraints
real_t m_appliedImpulse = 0.0;
diff --git a/modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.cpp b/modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.cpp
index 226f8a0f7fef..a4fce809e31f 100644
--- a/modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.cpp
+++ b/modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.cpp
@@ -219,7 +219,7 @@ real_t GodotG6DOFTranslationalLimitMotor3D::solveLinearAxis(
//////////////////////////// GodotGeneric6DOFJoint3D ////////////////////////////////////
GodotGeneric6DOFJoint3D::GodotGeneric6DOFJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Transform3D &frameInA, const Transform3D &frameInB, bool useLinearReferenceFrameA) :
- GodotJoint3D(_arr, 2),
+ GodotJoint3D(),
m_frameInA(frameInA),
m_frameInB(frameInB),
m_useLinearReferenceFrameA(useLinearReferenceFrameA) {
diff --git a/modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.h b/modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.h
index 9ee6dd279176..3d0aa4efffe6 100644
--- a/modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.h
+++ b/modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.h
@@ -141,15 +141,6 @@ class GodotG6DOFTranslationalLimitMotor3D {
class GodotGeneric6DOFJoint3D : public GodotJoint3D {
protected:
- union {
- struct {
- GodotBody3D *A;
- GodotBody3D *B;
- };
-
- GodotBody3D *_arr[2] = { nullptr, nullptr };
- };
-
//! relative_frames
//!@{
Transform3D m_frameInA; //!< the constraint space w.r.t body A
diff --git a/modules/godot_physics_3d/joints/godot_hinge_joint_3d.cpp b/modules/godot_physics_3d/joints/godot_hinge_joint_3d.cpp
index 3d423f70e206..6580f08d35a9 100644
--- a/modules/godot_physics_3d/joints/godot_hinge_joint_3d.cpp
+++ b/modules/godot_physics_3d/joints/godot_hinge_joint_3d.cpp
@@ -50,7 +50,7 @@ subject to the following restrictions:
#include "godot_hinge_joint_3d.h"
GodotHingeJoint3D::GodotHingeJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Transform3D &frameA, const Transform3D &frameB) :
- GodotJoint3D(_arr, 2) {
+ GodotJoint3D() {
A = rbA;
B = rbB;
@@ -61,13 +61,12 @@ GodotHingeJoint3D::GodotHingeJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const T
m_rbBFrame.basis[1][2] *= real_t(-1.);
m_rbBFrame.basis[2][2] *= real_t(-1.);
- A->add_constraint(this, 0);
- B->add_constraint(this, 1);
+ add_constraint_to_bodies();
}
GodotHingeJoint3D::GodotHingeJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Vector3 &pivotInA, const Vector3 &pivotInB,
const Vector3 &axisInA, const Vector3 &axisInB) :
- GodotJoint3D(_arr, 2) {
+ GodotJoint3D() {
A = rbA;
B = rbB;
@@ -102,8 +101,7 @@ GodotHingeJoint3D::GodotHingeJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const V
rbAxisB1.y, rbAxisB2.y, -axisInB.y,
rbAxisB1.z, rbAxisB2.z, -axisInB.z);
- A->add_constraint(this, 0);
- B->add_constraint(this, 1);
+ add_constraint_to_bodies();
}
bool GodotHingeJoint3D::setup(real_t p_step) {
diff --git a/modules/godot_physics_3d/joints/godot_hinge_joint_3d.h b/modules/godot_physics_3d/joints/godot_hinge_joint_3d.h
index 7f835094684f..2a4b73373e9a 100644
--- a/modules/godot_physics_3d/joints/godot_hinge_joint_3d.h
+++ b/modules/godot_physics_3d/joints/godot_hinge_joint_3d.h
@@ -54,15 +54,6 @@ subject to the following restrictions:
*/
class GodotHingeJoint3D : public GodotJoint3D {
- union {
- struct {
- GodotBody3D *A;
- GodotBody3D *B;
- };
-
- GodotBody3D *_arr[2] = {};
- };
-
GodotJacobianEntry3D m_jac[3]; //3 orthogonal linear constraints
GodotJacobianEntry3D m_jacAng[3]; //2 orthogonal angular constraints+ 1 for limit/motor
diff --git a/modules/godot_physics_3d/joints/godot_pin_joint_3d.cpp b/modules/godot_physics_3d/joints/godot_pin_joint_3d.cpp
index 05ae0839e4f1..9572690737ce 100644
--- a/modules/godot_physics_3d/joints/godot_pin_joint_3d.cpp
+++ b/modules/godot_physics_3d/joints/godot_pin_joint_3d.cpp
@@ -167,14 +167,13 @@ real_t GodotPinJoint3D::get_param(PhysicsServer3D::PinJointParam p_param) const
}
GodotPinJoint3D::GodotPinJoint3D(GodotBody3D *p_body_a, const Vector3 &p_pos_a, GodotBody3D *p_body_b, const Vector3 &p_pos_b) :
- GodotJoint3D(_arr, 2) {
+ GodotJoint3D() {
A = p_body_a;
B = p_body_b;
m_pivotInA = p_pos_a;
m_pivotInB = p_pos_b;
- A->add_constraint(this, 0);
- B->add_constraint(this, 1);
+ add_constraint_to_bodies();
}
GodotPinJoint3D::~GodotPinJoint3D() {
diff --git a/modules/godot_physics_3d/joints/godot_pin_joint_3d.h b/modules/godot_physics_3d/joints/godot_pin_joint_3d.h
index 62d3068e094e..cb85406b763e 100644
--- a/modules/godot_physics_3d/joints/godot_pin_joint_3d.h
+++ b/modules/godot_physics_3d/joints/godot_pin_joint_3d.h
@@ -54,15 +54,6 @@ subject to the following restrictions:
*/
class GodotPinJoint3D : public GodotJoint3D {
- union {
- struct {
- GodotBody3D *A;
- GodotBody3D *B;
- };
-
- GodotBody3D *_arr[2] = {};
- };
-
real_t m_tau = 0.3; //bias
real_t m_damping = 1.0;
real_t m_impulseClamp = 0.0;
diff --git a/modules/godot_physics_3d/joints/godot_slider_joint_3d.cpp b/modules/godot_physics_3d/joints/godot_slider_joint_3d.cpp
index b9dca94b3775..fae75c5da2b6 100644
--- a/modules/godot_physics_3d/joints/godot_slider_joint_3d.cpp
+++ b/modules/godot_physics_3d/joints/godot_slider_joint_3d.cpp
@@ -58,14 +58,13 @@ April 04, 2008
//-----------------------------------------------------------------------------
GodotSliderJoint3D::GodotSliderJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Transform3D &frameInA, const Transform3D &frameInB) :
- GodotJoint3D(_arr, 2),
+ GodotJoint3D(),
m_frameInA(frameInA),
m_frameInB(frameInB) {
A = rbA;
B = rbB;
- A->add_constraint(this, 0);
- B->add_constraint(this, 1);
+ add_constraint_to_bodies();
}
//-----------------------------------------------------------------------------
diff --git a/modules/godot_physics_3d/joints/godot_slider_joint_3d.h b/modules/godot_physics_3d/joints/godot_slider_joint_3d.h
index 99fabf863840..2f2cb40d9a1c 100644
--- a/modules/godot_physics_3d/joints/godot_slider_joint_3d.h
+++ b/modules/godot_physics_3d/joints/godot_slider_joint_3d.h
@@ -67,15 +67,6 @@ April 04, 2008
class GodotSliderJoint3D : public GodotJoint3D {
protected:
- union {
- struct {
- GodotBody3D *A;
- GodotBody3D *B;
- };
-
- GodotBody3D *_arr[2] = { nullptr, nullptr };
- };
-
Transform3D m_frameInA;
Transform3D m_frameInB;
diff --git a/modules/sandbox b/modules/sandbox
new file mode 120000
index 000000000000..8646b7e76b12
--- /dev/null
+++ b/modules/sandbox
@@ -0,0 +1 @@
+../../sandbox
\ No newline at end of file
diff --git a/scene/2d/physics/joints/damped_spring_joint_2d.cpp b/scene/2d/physics/joints/damped_spring_joint_2d.cpp
index 4b210ec0c74a..4269f45a236d 100644
--- a/scene/2d/physics/joints/damped_spring_joint_2d.cpp
+++ b/scene/2d/physics/joints/damped_spring_joint_2d.cpp
@@ -47,6 +47,14 @@ void DampedSpringJoint2D::_notification(int p_what) {
draw_line(Point2(-10, length), Point2(+10, length), Color(0.7, 0.6, 0.0, 0.5), 3);
draw_line(Point2(0, 0), Point2(0, length), Color(0.7, 0.6, 0.0, 0.5), 3);
} break;
+
+ case NOTIFICATION_DISABLED: {
+ _apply_disabled();
+ } break;
+
+ case NOTIFICATION_ENABLED: {
+ _apply_enabled();
+ } break;
}
}
diff --git a/scene/2d/physics/joints/groove_joint_2d.cpp b/scene/2d/physics/joints/groove_joint_2d.cpp
index 415a49d8bd5c..d04867c4b6db 100644
--- a/scene/2d/physics/joints/groove_joint_2d.cpp
+++ b/scene/2d/physics/joints/groove_joint_2d.cpp
@@ -48,6 +48,14 @@ void GrooveJoint2D::_notification(int p_what) {
draw_line(Point2(0, 0), Point2(0, length), Color(0.7, 0.6, 0.0, 0.5), 3);
draw_line(Point2(-10, initial_offset), Point2(+10, initial_offset), Color(0.8, 0.8, 0.9, 0.5), 5);
} break;
+
+ case NOTIFICATION_DISABLED: {
+ _apply_disabled();
+ } break;
+
+ case NOTIFICATION_ENABLED: {
+ _apply_enabled();
+ } break;
}
}
diff --git a/scene/2d/physics/joints/joint_2d.cpp b/scene/2d/physics/joints/joint_2d.cpp
index a32bcbae7883..a9dc4b3ff45c 100644
--- a/scene/2d/physics/joints/joint_2d.cpp
+++ b/scene/2d/physics/joints/joint_2d.cpp
@@ -66,6 +66,11 @@ void Joint2D::_update_joint(bool p_only_free) {
warning = String();
return;
}
+ if (!is_enabled() && disable_mode == DISABLE_MODE_REMOVE) {
+ PhysicsServer2D::get_singleton()->joint_set_enabled(get_rid(), false);
+ warning = String();
+ return;
+ }
Node *node_a = get_node_or_null(a);
Node *node_b = get_node_or_null(b);
@@ -185,9 +190,69 @@ void Joint2D::_notification(int p_what) {
}
_update_joint(true);
} break;
+
+ case NOTIFICATION_DISABLED: {
+ _apply_disabled();
+ } break;
+
+ case NOTIFICATION_ENABLED: {
+ _apply_enabled();
+ } break;
+ }
+}
+
+void Joint2D::_apply_disabled() {
+ switch (disable_mode) {
+ case DISABLE_MODE_REMOVE: {
+ if (is_inside_tree()) {
+ PhysicsServer2D::get_singleton()->joint_set_enabled(get_rid(), false);
+ }
+ } break;
+
+ case DISABLE_MODE_KEEP_ACTIVE: {
+ // Nothing to do.
+ } break;
}
}
+void Joint2D::_apply_enabled() {
+ switch (disable_mode) {
+ case DISABLE_MODE_REMOVE: {
+ if (is_inside_tree()) {
+ PhysicsServer2D::get_singleton()->joint_set_enabled(get_rid(), true);
+ }
+ } break;
+
+ case DISABLE_MODE_KEEP_ACTIVE: {
+ // Nothing to do.
+ } break;
+ }
+}
+
+void Joint2D::set_disable_mode(DisableMode p_mode) {
+ if (disable_mode == p_mode) {
+ return;
+ }
+
+ bool disabled = is_inside_tree() && !is_enabled();
+
+ if (disabled) {
+ // Cancel previous disable mode.
+ _apply_enabled();
+ }
+
+ disable_mode = p_mode;
+
+ if (disabled) {
+ // Apply new disable mode.
+ _apply_disabled();
+ }
+}
+
+Joint2D::DisableMode Joint2D::get_disable_mode() const {
+ return disable_mode;
+}
+
void Joint2D::set_bias(real_t p_bias) {
bias = p_bias;
if (joint.is_valid()) {
@@ -235,6 +300,9 @@ void Joint2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bias", "bias"), &Joint2D::set_bias);
ClassDB::bind_method(D_METHOD("get_bias"), &Joint2D::get_bias);
+ ClassDB::bind_method(D_METHOD("set_disable_mode", "mode"), &Joint2D::set_disable_mode);
+ ClassDB::bind_method(D_METHOD("get_disable_mode"), &Joint2D::get_disable_mode);
+
ClassDB::bind_method(D_METHOD("set_exclude_nodes_from_collision", "enable"), &Joint2D::set_exclude_nodes_from_collision);
ClassDB::bind_method(D_METHOD("get_exclude_nodes_from_collision"), &Joint2D::get_exclude_nodes_from_collision);
@@ -244,6 +312,10 @@ void Joint2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_b", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "PhysicsBody2D"), "set_node_b", "get_node_b");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bias", PROPERTY_HINT_RANGE, "0,0.9,0.001"), "set_bias", "get_bias");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_collision"), "set_exclude_nodes_from_collision", "get_exclude_nodes_from_collision");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "disable_mode", PROPERTY_HINT_ENUM, "Remove,Keep Active"), "set_disable_mode", "get_disable_mode");
+
+ BIND_ENUM_CONSTANT(DISABLE_MODE_REMOVE);
+ BIND_ENUM_CONSTANT(DISABLE_MODE_KEEP_ACTIVE);
}
Joint2D::Joint2D() {
diff --git a/scene/2d/physics/joints/joint_2d.h b/scene/2d/physics/joints/joint_2d.h
index bdd2730bfaf3..1909524a074c 100644
--- a/scene/2d/physics/joints/joint_2d.h
+++ b/scene/2d/physics/joints/joint_2d.h
@@ -38,6 +38,13 @@ class PhysicsBody2D;
class Joint2D : public Node2D {
GDCLASS(Joint2D, Node2D);
+public:
+ enum DisableMode {
+ DISABLE_MODE_REMOVE,
+ DISABLE_MODE_KEEP_ACTIVE,
+ };
+
+private:
RID joint;
RID ba, bb;
@@ -48,15 +55,21 @@ class Joint2D : public Node2D {
bool exclude_from_collision = true;
bool configured = false;
String warning;
+ DisableMode disable_mode = DISABLE_MODE_REMOVE;
protected:
void _disconnect_signals();
void _body_exit_tree();
void _update_joint(bool p_only_free = false);
+ void _apply_disabled();
+ void _apply_enabled();
+
void _notification(int p_what);
virtual void _configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) = 0;
+ void set_disable_mode(DisableMode p_mode);
+ DisableMode get_disable_mode() const;
static void _bind_methods();
_FORCE_INLINE_ bool is_configured() const { return configured; }
@@ -81,4 +94,5 @@ class Joint2D : public Node2D {
~Joint2D();
};
+VARIANT_ENUM_CAST(Joint2D::DisableMode);
#endif // JOINT_2D_H
diff --git a/scene/2d/physics/joints/pin_joint_2d.cpp b/scene/2d/physics/joints/pin_joint_2d.cpp
index 6ff0c485f575..9c4965b866ac 100644
--- a/scene/2d/physics/joints/pin_joint_2d.cpp
+++ b/scene/2d/physics/joints/pin_joint_2d.cpp
@@ -46,6 +46,14 @@ void PinJoint2D::_notification(int p_what) {
draw_line(Point2(-10, 0), Point2(+10, 0), Color(0.7, 0.6, 0.0, 0.5), 3);
draw_line(Point2(0, -10), Point2(0, +10), Color(0.7, 0.6, 0.0, 0.5), 3);
} break;
+
+ case NOTIFICATION_DISABLED: {
+ _apply_disabled();
+ } break;
+
+ case NOTIFICATION_ENABLED: {
+ _apply_enabled();
+ } break;
}
}
diff --git a/scene/3d/physics/joints/joint_3d.cpp b/scene/3d/physics/joints/joint_3d.cpp
index 47c89f37e29b..119d32222eaf 100644
--- a/scene/3d/physics/joints/joint_3d.cpp
+++ b/scene/3d/physics/joints/joint_3d.cpp
@@ -66,6 +66,11 @@ void Joint3D::_update_joint(bool p_only_free) {
warning = String();
return;
}
+ if (!is_enabled() && disable_mode == DISABLE_MODE_REMOVE) {
+ PhysicsServer3D::get_singleton()->joint_set_enabled(get_rid(), false);
+ warning = String();
+ return;
+ }
Node *node_a = get_node_or_null(a);
Node *node_b = get_node_or_null(b);
@@ -181,8 +186,67 @@ void Joint3D::_notification(int p_what) {
}
_update_joint(true);
} break;
+
+ case NOTIFICATION_DISABLED: {
+ _apply_disabled();
+ } break;
+
+ case NOTIFICATION_ENABLED: {
+ _apply_enabled();
+ } break;
}
}
+ void Joint3D::_apply_disabled() {
+ switch (disable_mode) {
+ case DISABLE_MODE_REMOVE: {
+ if (is_inside_tree()) {
+ PhysicsServer3D::get_singleton()->joint_set_enabled(get_rid(), false);
+ }
+ } break;
+
+ case DISABLE_MODE_KEEP_ACTIVE: {
+ // Nothing to do.
+ } break;
+ }
+ }
+
+ void Joint3D::_apply_enabled() {
+ switch (disable_mode) {
+ case DISABLE_MODE_REMOVE: {
+ if (is_inside_tree()) {
+ PhysicsServer3D::get_singleton()->joint_set_enabled(get_rid(), true);
+ }
+ } break;
+
+ case DISABLE_MODE_KEEP_ACTIVE: {
+ // Nothing to do.
+ } break;
+ }
+ }
+
+ void Joint3D::set_disable_mode(DisableMode p_mode) {
+ if (disable_mode == p_mode) {
+ return;
+ }
+
+ bool disabled = is_inside_tree() && !is_enabled();
+
+ if (disabled) {
+ // Cancel previous disable mode.
+ _apply_enabled();
+ }
+
+ disable_mode = p_mode;
+
+ if (disabled) {
+ // Apply new disable mode.
+ _apply_disabled();
+ }
+ }
+
+ Joint3D::DisableMode Joint3D::get_disable_mode() const {
+ return disable_mode;
+ }
void Joint3D::set_exclude_nodes_from_collision(bool p_enable) {
if (exclude_from_collision == p_enable) {
@@ -223,6 +287,9 @@ void Joint3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_exclude_nodes_from_collision", "enable"), &Joint3D::set_exclude_nodes_from_collision);
ClassDB::bind_method(D_METHOD("get_exclude_nodes_from_collision"), &Joint3D::get_exclude_nodes_from_collision);
+ ClassDB::bind_method(D_METHOD("set_disable_mode", "mode"), &Joint3D::set_disable_mode);
+ ClassDB::bind_method(D_METHOD("get_disable_mode"), &Joint3D::get_disable_mode);
+
ClassDB::bind_method(D_METHOD("get_rid"), &Joint3D::get_rid);
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_a", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "PhysicsBody3D"), "set_node_a", "get_node_a");
@@ -230,6 +297,10 @@ void Joint3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "solver_priority", PROPERTY_HINT_RANGE, "1,8,1"), "set_solver_priority", "get_solver_priority");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exclude_nodes_from_collision"), "set_exclude_nodes_from_collision", "get_exclude_nodes_from_collision");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "disable_mode", PROPERTY_HINT_ENUM, "Remove,Keep Active"), "set_disable_mode", "get_disable_mode");
+
+ BIND_ENUM_CONSTANT(DISABLE_MODE_REMOVE);
+ BIND_ENUM_CONSTANT(DISABLE_MODE_KEEP_ACTIVE);
}
Joint3D::Joint3D() {
diff --git a/scene/3d/physics/joints/joint_3d.h b/scene/3d/physics/joints/joint_3d.h
index ed502ab2459e..5a948095438f 100644
--- a/scene/3d/physics/joints/joint_3d.h
+++ b/scene/3d/physics/joints/joint_3d.h
@@ -37,6 +37,13 @@
class Joint3D : public Node3D {
GDCLASS(Joint3D, Node3D);
+public:
+ enum DisableMode {
+ DISABLE_MODE_REMOVE,
+ DISABLE_MODE_KEEP_ACTIVE,
+ };
+
+private:
RID ba, bb;
RID joint;
@@ -49,6 +56,11 @@ class Joint3D : public Node3D {
String warning;
bool configured = false;
+ void _apply_disabled();
+ void _apply_enabled();
+
+ DisableMode disable_mode = DISABLE_MODE_REMOVE;
+
protected:
void _disconnect_signals();
void _body_exit_tree();
@@ -58,6 +70,9 @@ class Joint3D : public Node3D {
virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) = 0;
+ void set_disable_mode(DisableMode p_mode);
+ DisableMode get_disable_mode() const;
+
static void _bind_methods();
_FORCE_INLINE_ bool is_configured() const { return configured; }
@@ -82,4 +97,5 @@ class Joint3D : public Node3D {
~Joint3D();
};
+VARIANT_ENUM_CAST(Joint3D::DisableMode);
#endif // JOINT_3D_H
diff --git a/servers/extensions/physics_server_2d_extension.cpp b/servers/extensions/physics_server_2d_extension.cpp
index f8e78d655f49..c7384efacfb8 100644
--- a/servers/extensions/physics_server_2d_extension.cpp
+++ b/servers/extensions/physics_server_2d_extension.cpp
@@ -306,6 +306,9 @@ void PhysicsServer2DExtension::_bind_methods() {
GDVIRTUAL_BIND(_joint_create);
GDVIRTUAL_BIND(_joint_clear, "joint");
+ GDVIRTUAL_BIND(_joint_set_enabled, "joint", "enabled");
+ GDVIRTUAL_BIND(_joint_is_enabled, "joint");
+
GDVIRTUAL_BIND(_joint_set_param, "joint", "param", "value");
GDVIRTUAL_BIND(_joint_get_param, "joint", "param");
diff --git a/servers/extensions/physics_server_2d_extension.h b/servers/extensions/physics_server_2d_extension.h
index 7bbd84ddf4ff..621cd1fa0b5c 100644
--- a/servers/extensions/physics_server_2d_extension.h
+++ b/servers/extensions/physics_server_2d_extension.h
@@ -409,6 +409,9 @@ class PhysicsServer2DExtension : public PhysicsServer2D {
EXBIND0R(RID, joint_create)
EXBIND1(joint_clear, RID)
+ EXBIND3(joint_set_enabled, RID, bool)
+ EXBIND2RC(bool, joint_is_enabled, RID)
+
EXBIND3(joint_set_param, RID, JointParam, real_t)
EXBIND2RC(real_t, joint_get_param, RID, JointParam)
diff --git a/servers/extensions/physics_server_3d_extension.cpp b/servers/extensions/physics_server_3d_extension.cpp
index 0937021c641f..d118243aefdc 100644
--- a/servers/extensions/physics_server_3d_extension.cpp
+++ b/servers/extensions/physics_server_3d_extension.cpp
@@ -363,6 +363,9 @@ void PhysicsServer3DExtension::_bind_methods() {
GDVIRTUAL_BIND(_joint_create);
GDVIRTUAL_BIND(_joint_clear, "joint");
+ GDVIRTUAL_BIND(_joint_set_enabled, "joint", "enabled");
+ GDVIRTUAL_BIND(_joint_is_enabled, "joint");
+
GDVIRTUAL_BIND(_joint_make_pin, "joint", "body_A", "local_A", "body_B", "local_B");
GDVIRTUAL_BIND(_pin_joint_set_param, "joint", "param", "value");
diff --git a/servers/extensions/physics_server_3d_extension.h b/servers/extensions/physics_server_3d_extension.h
index b808b80b938b..605cabb07280 100644
--- a/servers/extensions/physics_server_3d_extension.h
+++ b/servers/extensions/physics_server_3d_extension.h
@@ -472,6 +472,9 @@ class PhysicsServer3DExtension : public PhysicsServer3D {
EXBIND0R(RID, joint_create)
EXBIND1(joint_clear, RID)
+ EXBIND3(joint_set_enabled, RID, JointFlag, bool)
+ EXBIND2RC(bool, joint_is_enabled, RID, JointFlag)
+
EXBIND5(joint_make_pin, RID, RID, const Vector3 &, RID, const Vector3 &)
EXBIND3(pin_joint_set_param, RID, PinJointParam, real_t)
diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp
index f4f9a2e8b759..ceb69a02ebff 100644
--- a/servers/physics_server_2d.cpp
+++ b/servers/physics_server_2d.cpp
@@ -768,6 +768,9 @@ void PhysicsServer2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("joint_clear", "joint"), &PhysicsServer2D::joint_clear);
+ ClassDB::bind_method(D_METHOD("joint_set_enabled", "joint", "enabled"), &PhysicsServer2D::joint_set_enabled);
+ ClassDB::bind_method(D_METHOD("joint_is_enabled", "joint"), &PhysicsServer2D::joint_is_enabled);
+
ClassDB::bind_method(D_METHOD("joint_set_param", "joint", "param", "value"), &PhysicsServer2D::joint_set_param);
ClassDB::bind_method(D_METHOD("joint_get_param", "joint", "param"), &PhysicsServer2D::joint_get_param);
diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h
index 67fc0ed899d5..b3d28f9fb64a 100644
--- a/servers/physics_server_2d.h
+++ b/servers/physics_server_2d.h
@@ -536,6 +536,9 @@ class PhysicsServer2D : public Object {
JOINT_TYPE_MAX
};
+ virtual void joint_set_enabled(RID p_joint, bool p_enabled) = 0;
+ virtual bool joint_is_enabled(RID p_joint) const = 0;
+
enum JointParam {
JOINT_PARAM_BIAS,
JOINT_PARAM_MAX_BIAS,
diff --git a/servers/physics_server_2d_dummy.h b/servers/physics_server_2d_dummy.h
index 1f211d7ce098..76e15c5f7369 100644
--- a/servers/physics_server_2d_dummy.h
+++ b/servers/physics_server_2d_dummy.h
@@ -303,6 +303,9 @@ class PhysicsServer2DDummy : public PhysicsServer2D {
virtual void joint_clear(RID p_joint) override {}
+ virtual void joint_set_enabled(RID p_joint, bool p_enabled) override {}
+ virtual bool joint_is_enabled(RID p_joint) const override { return false; }
+
virtual void joint_set_param(RID p_joint, JointParam p_param, real_t p_value) override {}
virtual real_t joint_get_param(RID p_joint, JointParam p_param) const override { return 0; }
diff --git a/servers/physics_server_2d_wrap_mt.h b/servers/physics_server_2d_wrap_mt.h
index 5c757264b3b7..2fbe4d1a4806 100644
--- a/servers/physics_server_2d_wrap_mt.h
+++ b/servers/physics_server_2d_wrap_mt.h
@@ -276,8 +276,8 @@ class PhysicsServer2DWrapMT : public PhysicsServer2D {
FUNC1(joint_clear, RID)
- FUNC3(joint_set_param, RID, JointParam, real_t);
- FUNC2RC(real_t, joint_get_param, RID, JointParam);
+ FUNC2(joint_set_enabled, RID, bool);
+ FUNC1RC(bool, joint_is_enabled, RID);
FUNC2(joint_disable_collisions_between_bodies, RID, const bool);
FUNC1RC(bool, joint_is_disabled_collisions_between_bodies, RID);
diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp
index 312b67ada955..a30dbe4daf7b 100644
--- a/servers/physics_server_3d.cpp
+++ b/servers/physics_server_3d.cpp
@@ -900,6 +900,9 @@ void PhysicsServer3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("joint_create"), &PhysicsServer3D::joint_create);
ClassDB::bind_method(D_METHOD("joint_clear", "joint"), &PhysicsServer3D::joint_clear);
+ ClassDB::bind_method(D_METHOD("joint_set_enabled", "joint", "enabled"), &PhysicsServer3D::joint_set_enabled);
+ ClassDB::bind_method(D_METHOD("joint_is_enabled", "joint"), &PhysicsServer3D::joint_is_enabled);
+
BIND_ENUM_CONSTANT(JOINT_TYPE_PIN);
BIND_ENUM_CONSTANT(JOINT_TYPE_HINGE);
BIND_ENUM_CONSTANT(JOINT_TYPE_SLIDER);
diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h
index 33def7cf8d44..f18eaf1c3882 100644
--- a/servers/physics_server_3d.h
+++ b/servers/physics_server_3d.h
@@ -640,6 +640,9 @@ class PhysicsServer3D : public Object {
virtual void joint_clear(RID p_joint) = 0;
+ virtual void joint_set_enabled(RID p_joint, bool p_enabled) = 0;
+ virtual bool joint_is_enabled(RID p_joint) const = 0;
+
virtual JointType joint_get_type(RID p_joint) const = 0;
virtual void joint_set_solver_priority(RID p_joint, int p_priority) = 0;
diff --git a/servers/physics_server_3d_dummy.h b/servers/physics_server_3d_dummy.h
index 209a541fea01..a771db07add6 100644
--- a/servers/physics_server_3d_dummy.h
+++ b/servers/physics_server_3d_dummy.h
@@ -364,6 +364,9 @@ class PhysicsServer3DDummy : public PhysicsServer3D {
virtual void joint_clear(RID p_joint) override {}
+ virtual void joint_set_enabled(RID p_joint, bool p_enabled) override {}
+ virtual bool joint_is_enabled(RID p_joint) const override { return false; }
+
virtual JointType joint_get_type(RID p_joint) const override { return JointType::JOINT_TYPE_PIN; }
virtual void joint_set_solver_priority(RID p_joint, int p_priority) override {}
diff --git a/servers/physics_server_3d_wrap_mt.h b/servers/physics_server_3d_wrap_mt.h
index 2fd39546a59e..3790d20719d6 100644
--- a/servers/physics_server_3d_wrap_mt.h
+++ b/servers/physics_server_3d_wrap_mt.h
@@ -331,6 +331,9 @@ class PhysicsServer3DWrapMT : public PhysicsServer3D {
FUNC1(joint_clear, RID)
+ FUNC2(joint_set_enabled, RID, bool)
+ FUNC1RC(bool, joint_is_enabled, RID)
+
FUNC5(joint_make_pin, RID, RID, const Vector3 &, RID, const Vector3 &)
FUNC3(pin_joint_set_param, RID, PinJointParam, real_t)