summaryrefslogtreecommitdiff
path: root/scene/2d/joints_2d.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/2d/joints_2d.cpp')
-rw-r--r--scene/2d/joints_2d.cpp115
1 files changed, 73 insertions, 42 deletions
diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joints_2d.cpp
index 3e37f2d2bb..7d9cdd52ac 100644
--- a/scene/2d/joints_2d.cpp
+++ b/scene/2d/joints_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,56 +32,79 @@
#include "core/config/engine.h"
#include "physics_body_2d.h"
+#include "scene/scene_string_names.h"
#include "servers/physics_server_2d.h"
-void Joint2D::_update_joint(bool p_only_free) {
- if (joint.is_valid()) {
- if (ba.is_valid() && bb.is_valid() && exclude_from_collision) {
- PhysicsServer2D::get_singleton()->joint_disable_collisions_between_bodies(joint, false);
- }
+void Joint2D::_disconnect_signals() {
+ Node *node_a = get_node_or_null(a);
+ PhysicsBody2D *body_a = Object::cast_to<PhysicsBody2D>(node_a);
+ if (body_a) {
+ body_a->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint2D::_body_exit_tree));
+ }
+
+ Node *node_b = get_node_or_null(b);
+ PhysicsBody2D *body_b = Object::cast_to<PhysicsBody2D>(node_b);
+ if (body_b) {
+ body_b->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint2D::_body_exit_tree));
+ }
+}
+
+void Joint2D::_body_exit_tree() {
+ _disconnect_signals();
+ _update_joint(true);
+}
- PhysicsServer2D::get_singleton()->free(joint);
- joint = RID();
- ba = RID();
- bb = RID();
+void Joint2D::_update_joint(bool p_only_free) {
+ if (ba.is_valid() && bb.is_valid() && exclude_from_collision) {
+ PhysicsServer2D::get_singleton()->joint_disable_collisions_between_bodies(joint, false);
}
+ ba = RID();
+ bb = RID();
+ configured = false;
+
if (p_only_free || !is_inside_tree()) {
+ PhysicsServer2D::get_singleton()->joint_clear(joint);
warning = String();
return;
}
- Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)nullptr;
- Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)nullptr;
+ Node *node_a = get_node_or_null(a);
+ Node *node_b = get_node_or_null(b);
PhysicsBody2D *body_a = Object::cast_to<PhysicsBody2D>(node_a);
PhysicsBody2D *body_b = Object::cast_to<PhysicsBody2D>(node_b);
if (node_a && !body_a && node_b && !body_b) {
+ PhysicsServer2D::get_singleton()->joint_clear(joint);
warning = TTR("Node A and Node B must be PhysicsBody2Ds");
update_configuration_warning();
return;
}
if (node_a && !body_a) {
+ PhysicsServer2D::get_singleton()->joint_clear(joint);
warning = TTR("Node A must be a PhysicsBody2D");
update_configuration_warning();
return;
}
if (node_b && !body_b) {
+ PhysicsServer2D::get_singleton()->joint_clear(joint);
warning = TTR("Node B must be a PhysicsBody2D");
update_configuration_warning();
return;
}
if (!body_a || !body_b) {
+ PhysicsServer2D::get_singleton()->joint_clear(joint);
warning = TTR("Joint is not connected to two PhysicsBody2Ds");
update_configuration_warning();
return;
}
if (body_a == body_b) {
+ PhysicsServer2D::get_singleton()->joint_clear(joint);
warning = TTR("Node A and Node B must be different PhysicsBody2Ds");
update_configuration_warning();
return;
@@ -98,7 +121,9 @@ void Joint2D::_update_joint(bool p_only_free) {
body_b->force_update_transform();
}
- joint = _configure_joint(body_a, body_b);
+ configured = true;
+
+ _configure_joint(joint, body_a, body_b);
ERR_FAIL_COND_MSG(!joint.is_valid(), "Failed to configure the joint.");
@@ -107,6 +132,9 @@ void Joint2D::_update_joint(bool p_only_free) {
ba = body_a->get_rid();
bb = body_b->get_rid();
+ body_a->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint2D::_body_exit_tree));
+ body_b->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint2D::_body_exit_tree));
+
PhysicsServer2D::get_singleton()->joint_disable_collisions_between_bodies(joint, exclude_from_collision);
}
@@ -115,6 +143,10 @@ void Joint2D::set_node_a(const NodePath &p_node_a) {
return;
}
+ if (joint.is_valid()) {
+ _disconnect_signals();
+ }
+
a = p_node_a;
_update_joint();
}
@@ -127,6 +159,11 @@ void Joint2D::set_node_b(const NodePath &p_node_b) {
if (b == p_node_b) {
return;
}
+
+ if (joint.is_valid()) {
+ _disconnect_signals();
+ }
+
b = p_node_b;
_update_joint();
}
@@ -142,6 +179,7 @@ void Joint2D::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
if (joint.is_valid()) {
+ _disconnect_signals();
_update_joint(true);
}
} break;
@@ -176,8 +214,8 @@ bool Joint2D::get_exclude_nodes_from_collision() const {
String Joint2D::get_configuration_warning() const {
String node_warning = Node2D::get_configuration_warning();
- if (!warning.empty()) {
- if (!node_warning.empty()) {
+ if (!warning.is_empty()) {
+ if (!node_warning.is_empty()) {
node_warning += "\n\n";
}
node_warning += warning;
@@ -206,8 +244,11 @@ void Joint2D::_bind_methods() {
}
Joint2D::Joint2D() {
- bias = 0;
- exclude_from_collision = true;
+ joint = PhysicsServer2D::get_singleton()->joint_create();
+}
+
+Joint2D::~Joint2D() {
+ PhysicsServer2D::get_singleton()->free(joint);
}
///////////////////////////////////////////////////////////////////////////////
@@ -231,16 +272,15 @@ void PinJoint2D::_notification(int p_what) {
}
}
-RID PinJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
- RID pj = PhysicsServer2D::get_singleton()->pin_joint_create(get_global_transform().get_origin(), body_a->get_rid(), body_b ? body_b->get_rid() : RID());
- PhysicsServer2D::get_singleton()->pin_joint_set_param(pj, PhysicsServer2D::PIN_JOINT_SOFTNESS, softness);
- return pj;
+void PinJoint2D::_configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
+ PhysicsServer2D::get_singleton()->joint_make_pin(p_joint, get_global_transform().get_origin(), 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);
}
void PinJoint2D::set_softness(real_t p_softness) {
softness = p_softness;
update();
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer2D::get_singleton()->pin_joint_set_param(get_joint(), PhysicsServer2D::PIN_JOINT_SOFTNESS, p_softness);
}
}
@@ -257,7 +297,6 @@ void PinJoint2D::_bind_methods() {
}
PinJoint2D::PinJoint2D() {
- softness = 0;
}
///////////////////////////////////////////////////////////////////////////////
@@ -283,13 +322,13 @@ void GrooveJoint2D::_notification(int p_what) {
}
}
-RID GrooveJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
+void GrooveJoint2D::_configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
Transform2D gt = get_global_transform();
Vector2 groove_A1 = gt.get_origin();
Vector2 groove_A2 = gt.xform(Vector2(0, length));
Vector2 anchor_B = gt.xform(Vector2(0, initial_offset));
- return PhysicsServer2D::get_singleton()->groove_joint_create(groove_A1, groove_A2, anchor_B, body_a->get_rid(), body_b->get_rid());
+ PhysicsServer2D::get_singleton()->joint_make_groove(p_joint, groove_A1, groove_A2, anchor_B, body_a->get_rid(), body_b->get_rid());
}
void GrooveJoint2D::set_length(real_t p_length) {
@@ -321,8 +360,6 @@ void GrooveJoint2D::_bind_methods() {
}
GrooveJoint2D::GrooveJoint2D() {
- length = 50;
- initial_offset = 25;
}
///////////////////////////////////////////////////////////////////////////////
@@ -347,19 +384,17 @@ void DampedSpringJoint2D::_notification(int p_what) {
}
}
-RID DampedSpringJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
+void DampedSpringJoint2D::_configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
Transform2D gt = get_global_transform();
Vector2 anchor_A = gt.get_origin();
Vector2 anchor_B = gt.xform(Vector2(0, length));
- RID dsj = PhysicsServer2D::get_singleton()->damped_spring_joint_create(anchor_A, anchor_B, body_a->get_rid(), body_b->get_rid());
+ PhysicsServer2D::get_singleton()->joint_make_damped_spring(p_joint, anchor_A, anchor_B, body_a->get_rid(), body_b->get_rid());
if (rest_length) {
- PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(dsj, PhysicsServer2D::DAMPED_SPRING_REST_LENGTH, rest_length);
+ PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(p_joint, PhysicsServer2D::DAMPED_SPRING_REST_LENGTH, rest_length);
}
- PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(dsj, PhysicsServer2D::DAMPED_SPRING_STIFFNESS, stiffness);
- PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(dsj, PhysicsServer2D::DAMPED_SPRING_DAMPING, damping);
-
- return dsj;
+ PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(p_joint, PhysicsServer2D::DAMPED_SPRING_STIFFNESS, stiffness);
+ PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(p_joint, PhysicsServer2D::DAMPED_SPRING_DAMPING, damping);
}
void DampedSpringJoint2D::set_length(real_t p_length) {
@@ -374,7 +409,7 @@ real_t DampedSpringJoint2D::get_length() const {
void DampedSpringJoint2D::set_rest_length(real_t p_rest_length) {
rest_length = p_rest_length;
update();
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(get_joint(), PhysicsServer2D::DAMPED_SPRING_REST_LENGTH, p_rest_length ? p_rest_length : length);
}
}
@@ -386,7 +421,7 @@ real_t DampedSpringJoint2D::get_rest_length() const {
void DampedSpringJoint2D::set_stiffness(real_t p_stiffness) {
stiffness = p_stiffness;
update();
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(get_joint(), PhysicsServer2D::DAMPED_SPRING_STIFFNESS, p_stiffness);
}
}
@@ -398,7 +433,7 @@ real_t DampedSpringJoint2D::get_stiffness() const {
void DampedSpringJoint2D::set_damping(real_t p_damping) {
damping = p_damping;
update();
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(get_joint(), PhysicsServer2D::DAMPED_SPRING_DAMPING, p_damping);
}
}
@@ -424,8 +459,4 @@ void DampedSpringJoint2D::_bind_methods() {
}
DampedSpringJoint2D::DampedSpringJoint2D() {
- length = 50;
- rest_length = 0;
- stiffness = 20;
- damping = 1;
}