Skip to content

Commit

Permalink
Disable joints when process mode is set for node to disable
Browse files Browse the repository at this point in the history
fix joint disable cases

fix copy from

update docs

add missing enum

update feedback

remove disable mode clear

upd

fix

update feedback

update feedback part 1

fix build

typo

fix
  • Loading branch information
Ughuuu committed Oct 31, 2024
1 parent ef8d981 commit a72975a
Show file tree
Hide file tree
Showing 43 changed files with 449 additions and 118 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 @@ -790,6 +790,13 @@
Sets 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_get_param" qualifiers="const">
<return type="float" />
<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 @@ -840,6 +840,13 @@
Overridable version of [method PhysicsServer2D.joint_disable_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_get_param" qualifiers="virtual const">
<return type="float" />
<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 @@ -855,6 +855,13 @@
Sets 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_get_solver_priority" qualifiers="const">
<return type="int" />
<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 @@ -783,6 +783,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_get_solver_priority" qualifiers="virtual const">
<return type="int" />
<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 @@ -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);
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 @@ -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;

Expand Down
Loading

0 comments on commit a72975a

Please sign in to comment.