Skip to content

Commit

Permalink
Merge pull request #258 from jss2a98aj/joint-disable
Browse files Browse the repository at this point in the history
Disable joints when process mode is set for node to disable
  • Loading branch information
jss2a98aj authored Jan 24, 2025
2 parents b410804 + fb9da02 commit e43203d
Show file tree
Hide file tree
Showing 42 changed files with 449 additions and 116 deletions.
12 changes: 12 additions & 0 deletions doc/classes/Joint2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,23 @@
<member name="disable_collision" type="bool" setter="set_exclude_nodes_from_collision" getter="get_exclude_nodes_from_collision" default="true">
If [code]true[/code], the two bodies bound together do not collide with each other.
</member>
<member name="disable_mode" type="int" setter="set_disable_mode" getter="get_disable_mode" enum="Joint2D.DisableMode" default="0">
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.
</member>
<member name="node_a" type="NodePath" setter="set_node_a" getter="get_node_a" default="NodePath(&quot;&quot;)">
Path to the first body (A) attached to the joint. The node must inherit [PhysicsBody2D].
</member>
<member name="node_b" type="NodePath" setter="set_node_b" getter="get_node_b" default="NodePath(&quot;&quot;)">
Path to the second body (B) attached to the joint. The node must inherit [PhysicsBody2D].
</member>
</members>
<constants>
<constant name="DISABLE_MODE_REMOVE" value="0" enum="DisableMode">
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.
</constant>
<constant name="DISABLE_MODE_KEEP_ACTIVE" value="1" enum="DisableMode">
When [member Node.process_mode] is set to [constant Node.PROCESS_MODE_DISABLED], do not affect the physics simulation.
</constant>
</constants>
</class>
12 changes: 12 additions & 0 deletions doc/classes/Joint3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
</method>
</methods>
<members>
<member name="disable_mode" type="int" setter="set_disable_mode" getter="get_disable_mode" enum="Joint3D.DisableMode" default="0">
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.
</member>
<member name="exclude_nodes_from_collision" type="bool" setter="set_exclude_nodes_from_collision" getter="get_exclude_nodes_from_collision" default="true">
If [code]true[/code], the two bodies bound together do not collide with each other.
</member>
Expand All @@ -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.
</member>
</members>
<constants>
<constant name="DISABLE_MODE_REMOVE" value="0" enum="DisableMode">
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.
</constant>
<constant name="DISABLE_MODE_KEEP_ACTIVE" value="1" enum="DisableMode">
When [member Node.process_mode] is set to [constant Node.PROCESS_MODE_DISABLED], do not affect the physics simulation.
</constant>
</constants>
</class>
15 changes: 15 additions & 0 deletions doc/classes/PhysicsServer2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,13 @@
Returns whether the bodies attached to the [Joint2D] will collide with each other.
</description>
</method>
<method name="joint_is_enabled" qualifiers="const">
<return type="bool" />
<param index="0" name="joint" type="RID" />
<description>
Gets joint enable state.
</description>
</method>
<method name="joint_make_damped_spring">
<return type="void" />
<param index="0" name="joint" type="RID" />
Expand Down Expand Up @@ -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].
</description>
</method>
<method name="joint_set_enabled">
<return type="void" />
<param index="0" name="joint" type="RID" />
<param index="1" name="enabled" type="bool" />
<description>
Enable or disable a joint.
</description>
</method>
<method name="joint_set_param">
<return type="void" />
<param index="0" name="joint" type="RID" />
Expand Down
15 changes: 15 additions & 0 deletions doc/classes/PhysicsServer2DExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,13 @@
Overridable version of [method PhysicsServer2D.joint_is_disabled_collisions_between_bodies].
</description>
</method>
<method name="_joint_is_enabled" qualifiers="virtual const">
<return type="bool" />
<param index="0" name="joint" type="RID" />
<description>
Overridable version of [method PhysicsServer2D.joint_is_enabled].
</description>
</method>
<method name="_joint_make_damped_spring" qualifiers="virtual">
<return type="void" />
<param index="0" name="joint" type="RID" />
Expand Down Expand Up @@ -895,6 +902,14 @@
Overridable version of [method PhysicsServer2D.joint_make_pin].
</description>
</method>
<method name="_joint_set_enabled" qualifiers="virtual">
<return type="void" />
<param index="0" name="joint" type="RID" />
<param index="1" name="enabled" type="bool" />
<description>
Overridable version of [method PhysicsServer2D.joint_set_enabled].
</description>
</method>
<method name="_joint_set_param" qualifiers="virtual">
<return type="void" />
<param index="0" name="joint" type="RID" />
Expand Down
15 changes: 15 additions & 0 deletions doc/classes/PhysicsServer3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,13 @@
Returns whether the bodies attached to the [Joint3D] will collide with each other.
</description>
</method>
<method name="joint_is_enabled" qualifiers="const">
<return type="bool" />
<param index="0" name="joint" type="RID" />
<description>
Gets the joint enabled state.
</description>
</method>
<method name="joint_make_cone_twist">
<return type="void" />
<param index="0" name="joint" type="RID" />
Expand Down Expand Up @@ -927,6 +934,14 @@
<description>
</description>
</method>
<method name="joint_set_enabled">
<return type="void" />
<param index="0" name="joint" type="RID" />
<param index="1" name="enabled" type="bool" />
<description>
Enable or disable the joint.
</description>
</method>
<method name="joint_set_solver_priority">
<return type="void" />
<param index="0" name="joint" type="RID" />
Expand Down
13 changes: 13 additions & 0 deletions doc/classes/PhysicsServer3DExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,12 @@
<description>
</description>
</method>
<method name="_joint_is_enabled" qualifiers="virtual const">
<return type="bool" />
<param index="0" name="joint" type="RID" />
<description>
</description>
</method>
<method name="_joint_make_cone_twist" qualifiers="virtual">
<return type="void" />
<param index="0" name="joint" type="RID" />
Expand Down Expand Up @@ -863,6 +869,13 @@
<description>
</description>
</method>
<method name="_joint_set_enabled" qualifiers="virtual">
<return type="void" />
<param index="0" name="joint" type="RID" />
<param index="1" name="enabled" type="bool" />
<description>
</description>
</method>
<method name="_joint_set_solver_priority" qualifiers="virtual">
<return type="void" />
<param index="0" name="joint" type="RID" />
Expand Down
17 changes: 7 additions & 10 deletions modules/godot_physics_2d/godot_joints_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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());
}
}
Expand Down Expand Up @@ -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;

Expand All @@ -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();
}

//////////////////////////////////////////////
Expand Down Expand Up @@ -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();
}
78 changes: 42 additions & 36 deletions modules/godot_physics_2d/godot_joints_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand All @@ -53,36 +81,32 @@ 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 {}

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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;

Expand Down
14 changes: 14 additions & 0 deletions modules/godot_physics_2d/godot_physics_server_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1080,6 +1080,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);
Expand Down
3 changes: 3 additions & 0 deletions modules/godot_physics_2d/godot_physics_server_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,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;

Expand Down
Loading

0 comments on commit e43203d

Please sign in to comment.