From e0e7332135c1fe0a01da415ef5cbf5b72041555c Mon Sep 17 00:00:00 2001 From: Marcel Admiraal Date: Wed, 25 Nov 2020 18:52:03 +0000 Subject: [PATCH] Check joint nodes and generate configuration warning messages. --- scene/2d/joints_2d.cpp | 60 +++++++++++++++++++++++++++++------ scene/2d/joints_2d.h | 3 ++ scene/3d/physics_joint.cpp | 64 ++++++++++++++++++++++++++++++++------ scene/3d/physics_joint.h | 3 ++ 4 files changed, 112 insertions(+), 18 deletions(-) diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joints_2d.cpp index 656ff456540..3f0ea38ed48 100644 --- a/scene/2d/joints_2d.cpp +++ b/scene/2d/joints_2d.cpp @@ -46,25 +46,53 @@ void Joint2D::_update_joint(bool p_only_free) { bb = RID(); } - if (p_only_free || !is_inside_tree()) + if (p_only_free || !is_inside_tree()) { + warning = String(); return; + } Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)NULL; Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)NULL; - if (!node_a || !node_b) - return; - PhysicsBody2D *body_a = Object::cast_to(node_a); PhysicsBody2D *body_b = Object::cast_to(node_b); - if (!body_a || !body_b) + if (node_a && !body_a && node_b && !body_b) { + warning = TTR("Node A and Node B must be PhysicsBody2Ds"); + update_configuration_warning(); return; + } + + if (node_a && !body_a) { + warning = TTR("Node A must be a PhysicsBody2D"); + update_configuration_warning(); + return; + } + + if (node_b && !body_b) { + warning = TTR("Node B must be a PhysicsBody2D"); + update_configuration_warning(); + return; + } + + if (!body_a || !body_b) { + warning = TTR("Joint is not connected to two PhysicsBody2Ds"); + update_configuration_warning(); + return; + } + + if (body_a == body_b) { + warning = TTR("Node A and Node B must be different PhysicsBody2Ds"); + update_configuration_warning(); + return; + } + + warning = String(); + update_configuration_warning(); joint = _configure_joint(body_a, body_b); - if (!joint.is_valid()) - return; + ERR_FAIL_COND_MSG(!joint.is_valid(), "Failed to configure the joint."); Physics2DServer::get_singleton()->get_singleton()->joint_set_param(joint, Physics2DServer::JOINT_PARAM_BIAS, bias); @@ -142,6 +170,20 @@ bool Joint2D::get_exclude_nodes_from_collision() const { return exclude_from_collision; } +String Joint2D::get_configuration_warning() const { + + String node_warning = Node2D::get_configuration_warning(); + + if (!warning.empty()) { + if (!node_warning.empty()) { + node_warning += "\n\n"; + } + node_warning += warning; + } + + return node_warning; +} + void Joint2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_node_a", "node"), &Joint2D::set_node_a); @@ -156,8 +198,8 @@ void Joint2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_exclude_nodes_from_collision", "enable"), &Joint2D::set_exclude_nodes_from_collision); ClassDB::bind_method(D_METHOD("get_exclude_nodes_from_collision"), &Joint2D::get_exclude_nodes_from_collision); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_a", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject2D"), "set_node_a", "get_node_a"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_b", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject2D"), "set_node_b", "get_node_b"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_a", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "PhysicsBody2D"), "set_node_a", "get_node_a"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_b", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "PhysicsBody2D"), "set_node_b", "get_node_b"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "bias", PROPERTY_HINT_RANGE, "0,0.9,0.001"), "set_bias", "get_bias"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_collision"), "set_exclude_nodes_from_collision", "get_exclude_nodes_from_collision"); } diff --git a/scene/2d/joints_2d.h b/scene/2d/joints_2d.h index f1750e56b6f..1de53977f64 100644 --- a/scene/2d/joints_2d.h +++ b/scene/2d/joints_2d.h @@ -47,6 +47,7 @@ class Joint2D : public Node2D { real_t bias; bool exclude_from_collision; + String warning; protected: void _update_joint(bool p_only_free = false); @@ -57,6 +58,8 @@ protected: static void _bind_methods(); public: + virtual String get_configuration_warning() const; + void set_node_a(const NodePath &p_node_a); NodePath get_node_a() const; diff --git a/scene/3d/physics_joint.cpp b/scene/3d/physics_joint.cpp index 7d6327d9a49..e692936e3f5 100644 --- a/scene/3d/physics_joint.cpp +++ b/scene/3d/physics_joint.cpp @@ -42,8 +42,10 @@ void Joint::_update_joint(bool p_only_free) { bb = RID(); } - if (p_only_free || !is_inside_tree()) + if (p_only_free || !is_inside_tree()) { + warning = String(); return; + } Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)NULL; Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)NULL; @@ -51,16 +53,46 @@ void Joint::_update_joint(bool p_only_free) { PhysicsBody *body_a = Object::cast_to(node_a); PhysicsBody *body_b = Object::cast_to(node_b); - if (!body_a && body_b) - SWAP(body_a, body_b); - - if (!body_a) + if (node_a && !body_a && node_b && !body_b) { + warning = TTR("Node A and Node B must be PhysicsBodies"); + update_configuration_warning(); return; + } + + if (node_a && !body_a) { + warning = TTR("Node A must be a PhysicsBody"); + update_configuration_warning(); + return; + } + + if (node_b && !body_b) { + warning = TTR("Node B must be a PhysicsBody"); + update_configuration_warning(); + return; + } + + if (!body_a && !body_b) { + warning = TTR("Joint is not connected to any PhysicsBodies"); + update_configuration_warning(); + return; + } + + if (body_a == body_b) { + warning = TTR("Node A and Node B must be different PhysicsBodies"); + update_configuration_warning(); + return; + } + + if (!body_a) { + SWAP(body_a, body_b); + } + + warning = String(); + update_configuration_warning(); joint = _configure_joint(body_a, body_b); - if (!joint.is_valid()) - return; + ERR_FAIL_COND_MSG(!joint.is_valid(), "Failed to configure the joint."); PhysicsServer::get_singleton()->joint_set_solver_priority(joint, solver_priority); @@ -137,6 +169,20 @@ bool Joint::get_exclude_nodes_from_collision() const { return exclude_from_collision; } +String Joint::get_configuration_warning() const { + + String node_warning = Node::get_configuration_warning(); + + if (!warning.empty()) { + if (!node_warning.empty()) { + node_warning += "\n\n"; + } + node_warning += warning; + } + + return node_warning; +} + void Joint::_bind_methods() { ClassDB::bind_method(D_METHOD("set_node_a", "node"), &Joint::set_node_a); @@ -151,8 +197,8 @@ void Joint::_bind_methods() { ClassDB::bind_method(D_METHOD("set_exclude_nodes_from_collision", "enable"), &Joint::set_exclude_nodes_from_collision); ClassDB::bind_method(D_METHOD("get_exclude_nodes_from_collision"), &Joint::get_exclude_nodes_from_collision); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "nodes/node_a", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject"), "set_node_a", "get_node_a"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "nodes/node_b", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject"), "set_node_b", "get_node_b"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "nodes/node_a", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "PhysicsBody"), "set_node_a", "get_node_a"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "nodes/node_b", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "PhysicsBody"), "set_node_b", "get_node_b"); ADD_PROPERTY(PropertyInfo(Variant::INT, "solver/priority", PROPERTY_HINT_RANGE, "1,8,1"), "set_solver_priority", "get_solver_priority"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision/exclude_nodes"), "set_exclude_nodes_from_collision", "get_exclude_nodes_from_collision"); diff --git a/scene/3d/physics_joint.h b/scene/3d/physics_joint.h index d03dbac392c..c7c357c84ab 100644 --- a/scene/3d/physics_joint.h +++ b/scene/3d/physics_joint.h @@ -47,6 +47,7 @@ class Joint : public Spatial { int solver_priority; bool exclude_from_collision; + String warning; protected: void _update_joint(bool p_only_free = false); @@ -58,6 +59,8 @@ protected: static void _bind_methods(); public: + virtual String get_configuration_warning() const; + void set_node_a(const NodePath &p_node_a); NodePath get_node_a() const;