diff options
Diffstat (limited to 'scene/2d/joints_2d.cpp')
-rw-r--r-- | scene/2d/joints_2d.cpp | 115 |
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; } |