Skip to content

Commit

Permalink
Merge pull request #81610 from Ughuuu/add-angle-limits-and-motor-to-p…
Browse files Browse the repository at this point in the history
…in-joint-2d

Update PinJoint2D API with angle limits and motor speed
  • Loading branch information
akien-mga committed Sep 26, 2023
2 parents 93cf990 + 0fcfb07 commit eefe161
Show file tree
Hide file tree
Showing 17 changed files with 361 additions and 9 deletions.
5 changes: 5 additions & 0 deletions COPYRIGHT.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ Copyright: 2001, Robert Penner
2007-2014, Juan Linietsky, Ariel Manzur
License: Expat

Files: ./servers/physics_2d/godot_joints_2d.cpp
Comment: Chipmunk2D Joint Constraints
Copyright: 2007, Scott Lembcke
License: Expat

Files: ./servers/physics_3d/collision_solver_3d_sat.cpp
Comment: Open Dynamics Engine
Copyright: 2001-2003, Russell L. Smith, Alen Ladavac, Nguyen Binh
Expand Down
32 changes: 32 additions & 0 deletions doc/classes/PhysicsServer2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,14 @@
Sets the value of the given joint parameter. See [enum JointParam] for the list of available parameters.
</description>
</method>
<method name="pin_joint_get_flag" qualifiers="const">
<return type="bool" />
<param index="0" name="joint" type="RID" />
<param index="1" name="flag" type="int" enum="PhysicsServer2D.PinJointFlag" />
<description>
Gets a pin joint flag (see [enum PinJointFlag] constants).
</description>
</method>
<method name="pin_joint_get_param" qualifiers="const">
<return type="float" />
<param index="0" name="joint" type="RID" />
Expand All @@ -847,6 +855,15 @@
Returns the value of a pin joint parameter. See [enum PinJointParam] for a list of available parameters.
</description>
</method>
<method name="pin_joint_set_flag">
<return type="void" />
<param index="0" name="joint" type="RID" />
<param index="1" name="flag" type="int" enum="PhysicsServer2D.PinJointFlag" />
<param index="2" name="enabled" type="bool" />
<description>
Sets a pin joint flag (see [enum PinJointFlag] constants).
</description>
</method>
<method name="pin_joint_set_param">
<return type="void" />
<param index="0" name="joint" type="RID" />
Expand Down Expand Up @@ -1160,6 +1177,21 @@
<constant name="PIN_JOINT_SOFTNESS" value="0" enum="PinJointParam">
Constant to set/get a how much the bond of the pin joint can flex. The default value of this parameter is [code]0.0[/code].
</constant>
<constant name="PIN_JOINT_LIMIT_UPPER" value="1" enum="PinJointParam">
The maximum rotation around the pin.
</constant>
<constant name="PIN_JOINT_LIMIT_LOWER" value="2" enum="PinJointParam">
The minimum rotation around the pin.
</constant>
<constant name="PIN_JOINT_MOTOR_TARGET_VELOCITY" value="3" enum="PinJointParam">
Target speed for the motor. In radians per second.
</constant>
<constant name="PIN_JOINT_FLAG_ANGULAR_LIMIT_ENABLED" value="0" enum="PinJointFlag">
If [code]true[/code], the pin has a maximum and a minimum rotation.
</constant>
<constant name="PIN_JOINT_FLAG_MOTOR_ENABLED" value="1" enum="PinJointFlag">
If [code]true[/code], a motor turns the pin.
</constant>
<constant name="DAMPED_SPRING_REST_LENGTH" value="0" enum="DampedSpringParam">
Sets the resting length of the spring joint. The joint will always try to go to back this length when pulled apart. The default value of this parameter is the distance between the joint's anchor points.
</constant>
Expand Down
15 changes: 15 additions & 0 deletions doc/classes/PhysicsServer2DExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -780,13 +780,28 @@
<description>
</description>
</method>
<method name="_pin_joint_get_flag" qualifiers="virtual const">
<return type="bool" />
<param index="0" name="joint" type="RID" />
<param index="1" name="flag" type="int" enum="PhysicsServer2D.PinJointFlag" />
<description>
</description>
</method>
<method name="_pin_joint_get_param" qualifiers="virtual const">
<return type="float" />
<param index="0" name="joint" type="RID" />
<param index="1" name="param" type="int" enum="PhysicsServer2D.PinJointParam" />
<description>
</description>
</method>
<method name="_pin_joint_set_flag" qualifiers="virtual">
<return type="void" />
<param index="0" name="joint" type="RID" />
<param index="1" name="flag" type="int" enum="PhysicsServer2D.PinJointFlag" />
<param index="2" name="enabled" type="bool" />
<description>
</description>
</method>
<method name="_pin_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/PinJoint2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,21 @@
<tutorials>
</tutorials>
<members>
<member name="angular_limit_enabled" type="bool" setter="set_angular_limit_enabled" getter="is_angular_limit_enabled" default="false">
If [code]true[/code], the pin maximum and minimum rotation, defined by [member angular_limit_lower] and [member angular_limit_upper] are applied.
</member>
<member name="angular_limit_lower" type="float" setter="set_angular_limit_lower" getter="get_angular_limit_lower" default="0.0">
The minimum rotation. Only active if [member angular_limit_enabled] is [code]true[/code].
</member>
<member name="angular_limit_upper" type="float" setter="set_angular_limit_upper" getter="get_angular_limit_upper" default="0.0">
The maximum rotation. Only active if [member angular_limit_enabled] is [code]true[/code].
</member>
<member name="motor_enabled" type="bool" setter="set_motor_enabled" getter="is_motor_enabled" default="false">
When activated, a motor turns the pin.
</member>
<member name="motor_target_velocity" type="float" setter="set_motor_target_velocity" getter="get_motor_target_velocity" default="0.0">
Target speed for the motor. In radians per second.
</member>
<member name="softness" type="float" setter="set_softness" getter="get_softness" default="0.0">
The higher this value, the more the bond to the pinned partner can flex.
</member>
Expand Down
100 changes: 100 additions & 0 deletions scene/2d/joint_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,17 @@ void PinJoint2D::_notification(int p_what) {
void PinJoint2D::_configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
PhysicsServer2D::get_singleton()->joint_make_pin(p_joint, get_global_position(), body_a->get_rid(), body_b ? body_b->get_rid() : RID());
PhysicsServer2D::get_singleton()->pin_joint_set_param(p_joint, PhysicsServer2D::PIN_JOINT_SOFTNESS, softness);
PhysicsServer2D::get_singleton()->pin_joint_set_param(p_joint, PhysicsServer2D::PIN_JOINT_LIMIT_UPPER, angular_limit_upper);
PhysicsServer2D::get_singleton()->pin_joint_set_param(p_joint, PhysicsServer2D::PIN_JOINT_LIMIT_LOWER, angular_limit_lower);
PhysicsServer2D::get_singleton()->pin_joint_set_param(p_joint, PhysicsServer2D::PIN_JOINT_MOTOR_TARGET_VELOCITY, motor_target_velocity);
PhysicsServer2D::get_singleton()->pin_joint_set_flag(p_joint, PhysicsServer2D::PIN_JOINT_FLAG_MOTOR_ENABLED, motor_enabled);
PhysicsServer2D::get_singleton()->pin_joint_set_flag(p_joint, PhysicsServer2D::PIN_JOINT_FLAG_ANGULAR_LIMIT_ENABLED, angular_limit_enabled);
}

void PinJoint2D::set_softness(real_t p_softness) {
if (softness == p_softness) {
return;
}
softness = p_softness;
queue_redraw();
if (is_configured()) {
Expand All @@ -291,11 +299,103 @@ real_t PinJoint2D::get_softness() const {
return softness;
}

void PinJoint2D::set_angular_limit_lower(real_t p_angular_limit_lower) {
if (angular_limit_lower == p_angular_limit_lower) {
return;
}
angular_limit_lower = p_angular_limit_lower;
queue_redraw();
if (is_configured()) {
PhysicsServer2D::get_singleton()->pin_joint_set_param(get_rid(), PhysicsServer2D::PIN_JOINT_LIMIT_LOWER, p_angular_limit_lower);
}
}

real_t PinJoint2D::get_angular_limit_lower() const {
return angular_limit_lower;
}

void PinJoint2D::set_angular_limit_upper(real_t p_angular_limit_upper) {
if (angular_limit_upper == p_angular_limit_upper) {
return;
}
angular_limit_upper = p_angular_limit_upper;
queue_redraw();
if (is_configured()) {
PhysicsServer2D::get_singleton()->pin_joint_set_param(get_rid(), PhysicsServer2D::PIN_JOINT_LIMIT_UPPER, p_angular_limit_upper);
}
}

real_t PinJoint2D::get_angular_limit_upper() const {
return angular_limit_upper;
}

void PinJoint2D::set_motor_target_velocity(real_t p_motor_target_velocity) {
if (motor_target_velocity == p_motor_target_velocity) {
return;
}
motor_target_velocity = p_motor_target_velocity;
queue_redraw();
if (is_configured()) {
PhysicsServer2D::get_singleton()->pin_joint_set_param(get_rid(), PhysicsServer2D::PIN_JOINT_MOTOR_TARGET_VELOCITY, motor_target_velocity);
}
}

real_t PinJoint2D::get_motor_target_velocity() const {
return motor_target_velocity;
}

void PinJoint2D::set_motor_enabled(bool p_motor_enabled) {
if (motor_enabled == p_motor_enabled) {
return;
}
motor_enabled = p_motor_enabled;
queue_redraw();
if (is_configured()) {
PhysicsServer2D::get_singleton()->pin_joint_set_flag(get_rid(), PhysicsServer2D::PIN_JOINT_FLAG_MOTOR_ENABLED, motor_enabled);
}
}

bool PinJoint2D::is_motor_enabled() const {
return motor_enabled;
}

void PinJoint2D::set_angular_limit_enabled(bool p_angular_limit_enabled) {
if (angular_limit_enabled == p_angular_limit_enabled) {
return;
}
angular_limit_enabled = p_angular_limit_enabled;
queue_redraw();
if (is_configured()) {
PhysicsServer2D::get_singleton()->pin_joint_set_flag(get_rid(), PhysicsServer2D::PIN_JOINT_FLAG_ANGULAR_LIMIT_ENABLED, angular_limit_enabled);
}
}

bool PinJoint2D::is_angular_limit_enabled() const {
return angular_limit_enabled;
}

void PinJoint2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_softness", "softness"), &PinJoint2D::set_softness);
ClassDB::bind_method(D_METHOD("get_softness"), &PinJoint2D::get_softness);
ClassDB::bind_method(D_METHOD("set_angular_limit_lower", "angular_limit_lower"), &PinJoint2D::set_angular_limit_lower);
ClassDB::bind_method(D_METHOD("get_angular_limit_lower"), &PinJoint2D::get_angular_limit_lower);
ClassDB::bind_method(D_METHOD("set_angular_limit_upper", "angular_limit_upper"), &PinJoint2D::set_angular_limit_upper);
ClassDB::bind_method(D_METHOD("get_angular_limit_upper"), &PinJoint2D::get_angular_limit_upper);
ClassDB::bind_method(D_METHOD("set_motor_target_velocity", "motor_target_velocity"), &PinJoint2D::set_motor_target_velocity);
ClassDB::bind_method(D_METHOD("get_motor_target_velocity"), &PinJoint2D::get_motor_target_velocity);
ClassDB::bind_method(D_METHOD("set_motor_enabled", "enabled"), &PinJoint2D::set_motor_enabled);
ClassDB::bind_method(D_METHOD("is_motor_enabled"), &PinJoint2D::is_motor_enabled);
ClassDB::bind_method(D_METHOD("set_angular_limit_enabled", "enabled"), &PinJoint2D::set_angular_limit_enabled);
ClassDB::bind_method(D_METHOD("is_angular_limit_enabled"), &PinJoint2D::is_angular_limit_enabled);

ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "softness", PROPERTY_HINT_RANGE, "0.00,16,0.01,exp"), "set_softness", "get_softness");
ADD_GROUP("Angular Limit", "angular_limit_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "angular_limit_enabled"), "set_angular_limit_enabled", "is_angular_limit_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit_lower", PROPERTY_HINT_RANGE, "-180,180,0.1,radians_as_degrees"), "set_angular_limit_lower", "get_angular_limit_lower");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit_upper", PROPERTY_HINT_RANGE, "-180,180,0.1,radians_as_degrees"), "set_angular_limit_upper", "get_angular_limit_upper");
ADD_GROUP("Motor", "motor_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "motor_enabled"), "set_motor_enabled", "is_motor_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "motor_target_velocity", PROPERTY_HINT_RANGE, U"-200,200,0.01,or_greater,or_less,radians_as_degrees,suffix:\u00B0/s"), "set_motor_target_velocity", "get_motor_target_velocity");
}

PinJoint2D::PinJoint2D() {
Expand Down
16 changes: 16 additions & 0 deletions scene/2d/joint_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ class PinJoint2D : public Joint2D {
GDCLASS(PinJoint2D, Joint2D);

real_t softness = 0.0;
real_t angular_limit_lower = 0.0;
real_t angular_limit_upper = 0.0;
real_t motor_target_velocity = 0.0;
bool motor_enabled = false;
bool angular_limit_enabled = false;

protected:
void _notification(int p_what);
Expand All @@ -94,6 +99,17 @@ class PinJoint2D : public Joint2D {
public:
void set_softness(real_t p_softness);
real_t get_softness() const;
void set_angular_limit_lower(real_t p_angular_limit_lower);
real_t get_angular_limit_lower() const;
void set_angular_limit_upper(real_t p_angular_limit_upper);
real_t get_angular_limit_upper() const;
void set_motor_target_velocity(real_t p_motor_target_velocity);
real_t get_motor_target_velocity() const;

void set_motor_enabled(bool p_motor_enabled);
bool is_motor_enabled() const;
void set_angular_limit_enabled(bool p_angular_limit_enabled);
bool is_angular_limit_enabled() const;

PinJoint2D();
};
Expand Down
3 changes: 3 additions & 0 deletions servers/extensions/physics_server_2d_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,9 @@ void PhysicsServer2DExtension::_bind_methods() {
GDVIRTUAL_BIND(_joint_make_groove, "joint", "a_groove1", "a_groove2", "b_anchor", "body_a", "body_b");
GDVIRTUAL_BIND(_joint_make_damped_spring, "joint", "anchor_a", "anchor_b", "body_a", "body_b");

GDVIRTUAL_BIND(_pin_joint_set_flag, "joint", "flag", "enabled");
GDVIRTUAL_BIND(_pin_joint_get_flag, "joint", "flag");

GDVIRTUAL_BIND(_pin_joint_set_param, "joint", "param", "value");
GDVIRTUAL_BIND(_pin_joint_get_param, "joint", "param");

Expand Down
3 changes: 3 additions & 0 deletions servers/extensions/physics_server_2d_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,9 @@ class PhysicsServer2DExtension : public PhysicsServer2D {
EXBIND6(joint_make_groove, RID, const Vector2 &, const Vector2 &, const Vector2 &, RID, RID)
EXBIND5(joint_make_damped_spring, RID, const Vector2 &, const Vector2 &, RID, RID)

EXBIND3(pin_joint_set_flag, RID, PinJointFlag, bool)
EXBIND2RC(bool, pin_joint_get_flag, RID, PinJointFlag)

EXBIND3(pin_joint_set_param, RID, PinJointParam, real_t)
EXBIND2RC(real_t, pin_joint_get_param, RID, PinJointParam)

Expand Down
Loading

0 comments on commit eefe161

Please sign in to comment.