Merge pull request #81610 from Ughuuu/add-angle-limits-and-motor-to-pin-joint-2d

Update PinJoint2D API with angle limits and motor speed
This commit is contained in:
Rémi Verschelde 2023-09-26 13:45:07 +02:00
commit eefe161549
No known key found for this signature in database
GPG key ID: C3336907360768E1
17 changed files with 361 additions and 9 deletions

View file

@ -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

View file

@ -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" />
@ -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" />
@ -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>

View file

@ -780,6 +780,13 @@
<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" />
@ -787,6 +794,14 @@
<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" />

View file

@ -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>

View file

@ -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()) {
@ -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() {

View file

@ -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);
@ -94,6 +99,17 @@ protected:
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();
};

View file

@ -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");

View file

@ -419,6 +419,9 @@ public:
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)

View file

@ -155,6 +155,9 @@ bool GodotPinJoint2D::setup(real_t p_step) {
bias = delta * -(get_bias() == 0 ? space->get_constraint_bias() : get_bias()) * (1.0 / p_step);
// Compute max impulse.
jn_max = get_max_force() * p_step;
return true;
}
@ -170,12 +173,41 @@ bool GodotPinJoint2D::pre_solve(real_t p_step) {
if (B && dynamic_B) {
B->apply_impulse(P, rB);
}
// Angle limits joint pre_solve step taken from https://github.com/slembcke/Chipmunk2D/blob/d0239ef4599b3688a5a336373f7d0a68426414ba/src/cpRotaryLimitJoint.c
real_t i_sum_local = A->get_inv_inertia();
if (B) {
i_sum_local += B->get_inv_inertia();
}
i_sum = 1.0 / (i_sum_local);
if (angular_limit_enabled && B) {
Vector2 diff_vector = B->get_transform().get_origin() - A->get_transform().get_origin();
diff_vector = diff_vector.rotated(-initial_angle);
real_t dist = diff_vector.angle();
real_t pdist = 0.0;
if (dist > angular_limit_upper) {
pdist = dist - angular_limit_upper;
} else if (dist < angular_limit_lower) {
pdist = dist - angular_limit_lower;
}
real_t error_bias = Math::pow(1.0 - 0.15, 60.0);
// Calculate bias velocity.
bias_velocity = -CLAMP((-1.0 - Math::pow(error_bias, p_step)) * pdist / p_step, -get_max_bias(), get_max_bias());
// If the bias velocity is 0, the joint is not at a limit.
if (bias_velocity >= -CMP_EPSILON && bias_velocity <= CMP_EPSILON) {
j_acc = 0;
is_joint_at_limit = false;
} else {
is_joint_at_limit = true;
}
} else {
bias_velocity = 0.0;
}
return true;
}
void GodotPinJoint2D::solve(real_t p_step) {
// compute relative velocity
// Compute relative velocity.
Vector2 vA = A->get_linear_velocity() - custom_cross(rA - A->get_center_of_mass(), A->get_angular_velocity());
Vector2 rel_vel;
@ -184,6 +216,33 @@ void GodotPinJoint2D::solve(real_t p_step) {
} else {
rel_vel = -vA;
}
// Angle limits joint solve step taken from https://github.com/slembcke/Chipmunk2D/blob/d0239ef4599b3688a5a336373f7d0a68426414ba/src/cpRotaryLimitJoint.c
if ((angular_limit_enabled || motor_enabled) && B) {
// Compute relative rotational velocity.
real_t wr = B->get_angular_velocity() - A->get_angular_velocity();
// Motor solve part taken from https://github.com/slembcke/Chipmunk2D/blob/d0239ef4599b3688a5a336373f7d0a68426414ba/src/cpSimpleMotor.c
if (motor_enabled) {
wr -= motor_target_velocity;
}
real_t j_max = jn_max;
// Compute normal impulse.
real_t j = -(bias_velocity + wr) * i_sum;
real_t j_old = j_acc;
// Only enable the limits if we have to.
if (angular_limit_enabled && is_joint_at_limit) {
if (bias_velocity < 0.0) {
j_acc = CLAMP(j_old + j, 0.0, j_max);
} else {
j_acc = CLAMP(j_old + j, -j_max, 0.0);
}
} else {
j_acc = CLAMP(j_old + j, -j_max, j_max);
}
j = j_acc - j_old;
A->apply_torque_impulse(-j * A->get_inv_inertia());
B->apply_torque_impulse(j * B->get_inv_inertia());
}
Vector2 impulse = M.basis_xform(bias - rel_vel - Vector2(softness, softness) * P);
@ -198,14 +257,59 @@ void GodotPinJoint2D::solve(real_t p_step) {
}
void GodotPinJoint2D::set_param(PhysicsServer2D::PinJointParam p_param, real_t p_value) {
if (p_param == PhysicsServer2D::PIN_JOINT_SOFTNESS) {
softness = p_value;
switch (p_param) {
case PhysicsServer2D::PIN_JOINT_SOFTNESS: {
softness = p_value;
} break;
case PhysicsServer2D::PIN_JOINT_LIMIT_UPPER: {
angular_limit_upper = p_value;
} break;
case PhysicsServer2D::PIN_JOINT_LIMIT_LOWER: {
angular_limit_lower = p_value;
} break;
case PhysicsServer2D::PIN_JOINT_MOTOR_TARGET_VELOCITY: {
motor_target_velocity = p_value;
} break;
}
}
real_t GodotPinJoint2D::get_param(PhysicsServer2D::PinJointParam p_param) const {
if (p_param == PhysicsServer2D::PIN_JOINT_SOFTNESS) {
return softness;
switch (p_param) {
case PhysicsServer2D::PIN_JOINT_SOFTNESS: {
return softness;
}
case PhysicsServer2D::PIN_JOINT_LIMIT_UPPER: {
return angular_limit_upper;
}
case PhysicsServer2D::PIN_JOINT_LIMIT_LOWER: {
return angular_limit_lower;
}
case PhysicsServer2D::PIN_JOINT_MOTOR_TARGET_VELOCITY: {
return motor_target_velocity;
}
}
ERR_FAIL_V(0);
}
void GodotPinJoint2D::set_flag(PhysicsServer2D::PinJointFlag p_flag, bool p_enabled) {
switch (p_flag) {
case PhysicsServer2D::PIN_JOINT_FLAG_ANGULAR_LIMIT_ENABLED: {
angular_limit_enabled = p_enabled;
} break;
case PhysicsServer2D::PIN_JOINT_FLAG_MOTOR_ENABLED: {
motor_enabled = p_enabled;
} break;
}
}
bool GodotPinJoint2D::get_flag(PhysicsServer2D::PinJointFlag p_flag) const {
switch (p_flag) {
case PhysicsServer2D::PIN_JOINT_FLAG_ANGULAR_LIMIT_ENABLED: {
return angular_limit_enabled;
}
case PhysicsServer2D::PIN_JOINT_FLAG_MOTOR_ENABLED: {
return motor_enabled;
}
}
ERR_FAIL_V(0);
}
@ -220,6 +324,7 @@ GodotPinJoint2D::GodotPinJoint2D(const Vector2 &p_pos, GodotBody2D *p_body_a, Go
p_body_a->add_constraint(this, 0);
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());
}
}

View file

@ -88,8 +88,19 @@ class GodotPinJoint2D : public GodotJoint2D {
Vector2 anchor_A;
Vector2 anchor_B;
Vector2 bias;
real_t initial_angle = 0.0;
real_t bias_velocity = 0.0;
real_t jn_max = 0.0;
real_t j_acc = 0.0;
real_t i_sum = 0.0;
Vector2 P;
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 is_joint_at_limit = false;
bool motor_enabled = false;
bool angular_limit_enabled = false;
public:
virtual PhysicsServer2D::JointType get_type() const override { return PhysicsServer2D::JOINT_TYPE_PIN; }
@ -101,6 +112,9 @@ public:
void set_param(PhysicsServer2D::PinJointParam p_param, real_t p_value);
real_t get_param(PhysicsServer2D::PinJointParam p_param) const;
void set_flag(PhysicsServer2D::PinJointFlag p_flag, bool p_enabled);
bool get_flag(PhysicsServer2D::PinJointFlag p_flag) const;
GodotPinJoint2D(const Vector2 &p_pos, GodotBody2D *p_body_a, GodotBody2D *p_body_b = nullptr);
};

View file

@ -1158,6 +1158,24 @@ void GodotPhysicsServer2D::joint_make_damped_spring(RID p_joint, const Vector2 &
memdelete(prev_joint);
}
void GodotPhysicsServer2D::pin_joint_set_flag(RID p_joint, PinJointFlag p_flag, bool p_enabled) {
GodotJoint2D *joint = joint_owner.get_or_null(p_joint);
ERR_FAIL_NULL(joint);
ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN);
GodotPinJoint2D *pin_joint = static_cast<GodotPinJoint2D *>(joint);
pin_joint->set_flag(p_flag, p_enabled);
}
bool GodotPhysicsServer2D::pin_joint_get_flag(RID p_joint, PinJointFlag p_flag) const {
GodotJoint2D *joint = joint_owner.get_or_null(p_joint);
ERR_FAIL_NULL_V(joint, 0);
ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, 0);
GodotPinJoint2D *pin_joint = static_cast<GodotPinJoint2D *>(joint);
return pin_joint->get_flag(p_flag);
}
void GodotPhysicsServer2D::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) {
GodotJoint2D *joint = joint_owner.get_or_null(p_joint);
ERR_FAIL_NULL(joint);

View file

@ -275,6 +275,8 @@ public:
virtual void joint_make_groove(RID p_joint, const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) override;
virtual void joint_make_damped_spring(RID p_joint, const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b = RID()) override;
virtual void pin_joint_set_flag(RID p_joint, PinJointFlag p_flag, bool p_enabled) override;
virtual bool pin_joint_get_flag(RID p_joint, PinJointFlag p_flag) const override;
virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) override;
virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const override;
virtual void damped_spring_joint_set_param(RID p_joint, DampedSpringParam p_param, real_t p_value) override;

View file

@ -1356,12 +1356,12 @@ real_t GodotPhysicsServer3D::hinge_joint_get_param(RID p_joint, HingeJointParam
return hinge_joint->get_param(p_param);
}
void GodotPhysicsServer3D::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) {
void GodotPhysicsServer3D::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_enabled) {
GodotJoint3D *joint = joint_owner.get_or_null(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_HINGE);
GodotHingeJoint3D *hinge_joint = static_cast<GodotHingeJoint3D *>(joint);
hinge_joint->set_flag(p_flag, p_value);
hinge_joint->set_flag(p_flag, p_enabled);
}
bool GodotPhysicsServer3D::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const {

View file

@ -776,6 +776,9 @@ void PhysicsServer2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("joint_make_groove", "joint", "groove1_a", "groove2_a", "anchor_b", "body_a", "body_b"), &PhysicsServer2D::joint_make_groove, DEFVAL(RID()), DEFVAL(RID()));
ClassDB::bind_method(D_METHOD("joint_make_damped_spring", "joint", "anchor_a", "anchor_b", "body_a", "body_b"), &PhysicsServer2D::joint_make_damped_spring, DEFVAL(RID()));
ClassDB::bind_method(D_METHOD("pin_joint_set_flag", "joint", "flag", "enabled"), &PhysicsServer2D::pin_joint_set_flag);
ClassDB::bind_method(D_METHOD("pin_joint_get_flag", "joint", "flag"), &PhysicsServer2D::pin_joint_get_flag);
ClassDB::bind_method(D_METHOD("pin_joint_set_param", "joint", "param", "value"), &PhysicsServer2D::pin_joint_set_param);
ClassDB::bind_method(D_METHOD("pin_joint_get_param", "joint", "param"), &PhysicsServer2D::pin_joint_get_param);
@ -863,6 +866,12 @@ void PhysicsServer2D::_bind_methods() {
BIND_ENUM_CONSTANT(JOINT_PARAM_MAX_FORCE);
BIND_ENUM_CONSTANT(PIN_JOINT_SOFTNESS);
BIND_ENUM_CONSTANT(PIN_JOINT_LIMIT_UPPER);
BIND_ENUM_CONSTANT(PIN_JOINT_LIMIT_LOWER);
BIND_ENUM_CONSTANT(PIN_JOINT_MOTOR_TARGET_VELOCITY);
BIND_ENUM_CONSTANT(PIN_JOINT_FLAG_ANGULAR_LIMIT_ENABLED);
BIND_ENUM_CONSTANT(PIN_JOINT_FLAG_MOTOR_ENABLED);
BIND_ENUM_CONSTANT(DAMPED_SPRING_REST_LENGTH);
BIND_ENUM_CONSTANT(DAMPED_SPRING_STIFFNESS);

View file

@ -553,12 +553,23 @@ public:
virtual void joint_make_damped_spring(RID p_joint, const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b = RID()) = 0;
enum PinJointParam {
PIN_JOINT_SOFTNESS
PIN_JOINT_SOFTNESS,
PIN_JOINT_LIMIT_UPPER,
PIN_JOINT_LIMIT_LOWER,
PIN_JOINT_MOTOR_TARGET_VELOCITY
};
virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) = 0;
virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const = 0;
enum PinJointFlag {
PIN_JOINT_FLAG_ANGULAR_LIMIT_ENABLED,
PIN_JOINT_FLAG_MOTOR_ENABLED
};
virtual void pin_joint_set_flag(RID p_joint, PinJointFlag p_flag, bool p_enabled) = 0;
virtual bool pin_joint_get_flag(RID p_joint, PinJointFlag p_flag) const = 0;
enum DampedSpringParam {
DAMPED_SPRING_REST_LENGTH,
DAMPED_SPRING_STIFFNESS,
@ -830,6 +841,7 @@ VARIANT_ENUM_CAST(PhysicsServer2D::CCDMode);
VARIANT_ENUM_CAST(PhysicsServer2D::JointParam);
VARIANT_ENUM_CAST(PhysicsServer2D::JointType);
VARIANT_ENUM_CAST(PhysicsServer2D::PinJointParam);
VARIANT_ENUM_CAST(PhysicsServer2D::PinJointFlag);
VARIANT_ENUM_CAST(PhysicsServer2D::DampedSpringParam);
VARIANT_ENUM_CAST(PhysicsServer2D::AreaBodyStatus);
VARIANT_ENUM_CAST(PhysicsServer2D::ProcessInfo);

View file

@ -297,6 +297,9 @@ public:
FUNC3(pin_joint_set_param, RID, PinJointParam, real_t);
FUNC2RC(real_t, pin_joint_get_param, RID, PinJointParam);
FUNC3(pin_joint_set_flag, RID, PinJointFlag, bool);
FUNC2RC(bool, pin_joint_get_flag, RID, PinJointFlag);
FUNC3(damped_spring_joint_set_param, RID, DampedSpringParam, real_t);
FUNC2RC(real_t, damped_spring_joint_get_param, RID, DampedSpringParam);

View file

@ -687,7 +687,7 @@ public:
virtual void hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) = 0;
virtual real_t hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const = 0;
virtual void hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) = 0;
virtual void hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_enabled) = 0;
virtual bool hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const = 0;
enum SliderJointParam {