diff --git a/scene/3d/bone_twist_disperser_3d.cpp b/scene/3d/bone_twist_disperser_3d.cpp index d1da52215a..8f129e4a7c 100644 --- a/scene/3d/bone_twist_disperser_3d.cpp +++ b/scene/3d/bone_twist_disperser_3d.cpp @@ -65,11 +65,7 @@ bool BoneTwistDisperser3D::_set(const StringName &p_path, const Variant &p_value } else if (what == "joints") { int idx = path.get_slicec('/', 3).to_int(); String prop = path.get_slicec('/', 4); - if (prop == "bone_name") { - set_joint_bone_name(which, idx, p_value); - } else if (prop == "bone") { - set_joint_bone(which, idx, p_value); - } else if (prop == "twist_amount") { + if (prop == "twist_amount") { set_joint_twist_amount(which, idx, p_value); } else { return false; @@ -163,7 +159,7 @@ void BoneTwistDisperser3D::_get_property_list(List *p_list) const for (uint32_t j = 0; j < settings[i]->joints.size(); j++) { String joint_path = path + "joints/" + itos(j) + "/"; props.push_back(PropertyInfo(Variant::STRING, joint_path + "bone_name", PROPERTY_HINT_ENUM_SUGGESTION, enum_hint, PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY)); - props.push_back(PropertyInfo(Variant::INT, joint_path + "bone", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_READ_ONLY)); + props.push_back(PropertyInfo(Variant::INT, joint_path + "bone", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_READ_ONLY)); props.push_back(PropertyInfo(Variant::FLOAT, joint_path + "twist_amount", PROPERTY_HINT_RANGE, "0,1,0.001,or_greater,or_less")); } } @@ -456,18 +452,6 @@ Ref BoneTwistDisperser3D::get_damping_curve(int p_index) const { // Individual joints. -void BoneTwistDisperser3D::set_joint_bone_name(int p_index, int p_joint, const String &p_bone_name) { - // Exists only for indicate bone name on the inspector, no needs to make dirty joint array. - ERR_FAIL_INDEX(p_index, (int)settings.size()); - LocalVector &joints = settings[p_index]->joints; - ERR_FAIL_INDEX(p_joint, (int)joints.size()); - joints[p_joint].joint.name = p_bone_name; - Skeleton3D *sk = get_skeleton(); - if (sk) { - set_joint_bone(p_index, p_joint, sk->find_bone(joints[p_joint].joint.name)); - } -} - String BoneTwistDisperser3D::get_joint_bone_name(int p_index, int p_joint) const { ERR_FAIL_INDEX_V(p_index, (int)settings.size(), String()); const LocalVector &joints = settings[p_index]->joints; @@ -475,7 +459,7 @@ String BoneTwistDisperser3D::get_joint_bone_name(int p_index, int p_joint) const return joints[p_joint].joint.name; } -void BoneTwistDisperser3D::set_joint_bone(int p_index, int p_joint, int p_bone) { +void BoneTwistDisperser3D::_set_joint_bone(int p_index, int p_joint, int p_bone) { ERR_FAIL_INDEX(p_index, (int)settings.size()); LocalVector &joints = settings[p_index]->joints; ERR_FAIL_INDEX(p_joint, (int)joints.size()); @@ -651,7 +635,7 @@ void BoneTwistDisperser3D::_update_joints(int p_index) { set_joint_count(p_index, new_joints.size()); for (uint32_t i = 0; i < new_joints.size(); i++) { - set_joint_bone(p_index, i, new_joints[i]); + _set_joint_bone(p_index, i, new_joints[i]); } _update_reference_bone(p_index); diff --git a/scene/3d/bone_twist_disperser_3d.h b/scene/3d/bone_twist_disperser_3d.h index d9bad0f7bb..8f15f1dba8 100644 --- a/scene/3d/bone_twist_disperser_3d.h +++ b/scene/3d/bone_twist_disperser_3d.h @@ -101,6 +101,8 @@ protected: void _make_joints_dirty(int p_index); void _update_joints(int p_index); + void _set_joint_bone(int p_index, int p_joint, int p_bone); + void _update_reference_bone(int p_index); void _update_curve(int p_index); @@ -146,9 +148,7 @@ public: Ref get_damping_curve(int p_index) const; // Individual joints. - void set_joint_bone_name(int p_index, int p_joint, const String &p_bone_name); String get_joint_bone_name(int p_index, int p_joint) const; - void set_joint_bone(int p_index, int p_joint, int p_bone); int get_joint_bone(int p_index, int p_joint) const; void set_joint_twist_amount(int p_index, int p_joint, float p_amount); diff --git a/scene/3d/chain_ik_3d.cpp b/scene/3d/chain_ik_3d.cpp index e2b46af374..b322490e61 100644 --- a/scene/3d/chain_ik_3d.cpp +++ b/scene/3d/chain_ik_3d.cpp @@ -59,16 +59,6 @@ bool ChainIK3D::_set(const StringName &p_path, const Variant &p_value) { set_extend_end_bone(which, p_value); } else if (what == "joint_count") { set_joint_count(which, p_value); - } else if (what == "joints") { - int idx = path.get_slicec('/', 3).to_int(); - String prop = path.get_slicec('/', 4); - if (prop == "bone_name") { - set_joint_bone_name(which, idx, p_value); - } else if (prop == "bone") { - set_joint_bone(which, idx, p_value); - } else { - return false; - } } else { return false; } @@ -144,7 +134,7 @@ void ChainIK3D::get_property_list(List *p_list) const { for (uint32_t j = 0; j < chain_settings[i]->joints.size(); j++) { String joint_path = path + "joints/" + itos(j) + "/"; props.push_back(PropertyInfo(Variant::STRING, joint_path + "bone_name", PROPERTY_HINT_ENUM_SUGGESTION, enum_hint, PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY)); - props.push_back(PropertyInfo(Variant::INT, joint_path + "bone", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_READ_ONLY)); + props.push_back(PropertyInfo(Variant::INT, joint_path + "bone", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_READ_ONLY)); } } @@ -308,18 +298,6 @@ float ChainIK3D::get_end_bone_length(int p_index) const { // Individual joints. -void ChainIK3D::set_joint_bone_name(int p_index, int p_joint, const String &p_bone_name) { - // Exists only for indicate bone name on the inspector, no needs to make dirty joint array. - ERR_FAIL_INDEX(p_index, (int)settings.size()); - LocalVector &joints = chain_settings[p_index]->joints; - ERR_FAIL_INDEX(p_joint, (int)joints.size()); - joints[p_joint].name = p_bone_name; - Skeleton3D *sk = get_skeleton(); - if (sk) { - set_joint_bone(p_index, p_joint, sk->find_bone(joints[p_joint].name)); - } -} - String ChainIK3D::get_joint_bone_name(int p_index, int p_joint) const { ERR_FAIL_INDEX_V(p_index, (int)settings.size(), String()); const LocalVector &joints = chain_settings[p_index]->joints; @@ -327,7 +305,7 @@ String ChainIK3D::get_joint_bone_name(int p_index, int p_joint) const { return joints[p_joint].name; } -void ChainIK3D::set_joint_bone(int p_index, int p_joint, int p_bone) { +void ChainIK3D::_set_joint_bone(int p_index, int p_joint, int p_bone) { ERR_FAIL_INDEX(p_index, (int)settings.size()); LocalVector &joints = chain_settings[p_index]->joints; ERR_FAIL_INDEX(p_joint, (int)joints.size()); @@ -471,7 +449,7 @@ void ChainIK3D::_update_joints(int p_index) { set_joint_count(p_index, new_joints.size()); for (uint32_t i = 0; i < new_joints.size(); i++) { - set_joint_bone(p_index, i, new_joints[i]); + _set_joint_bone(p_index, i, new_joints[i]); } if (sk) { diff --git a/scene/3d/chain_ik_3d.h b/scene/3d/chain_ik_3d.h index e7bec7dfbe..1833de35ab 100644 --- a/scene/3d/chain_ik_3d.h +++ b/scene/3d/chain_ik_3d.h @@ -216,6 +216,7 @@ protected: virtual void _make_all_joints_dirty() override; virtual void _update_joints(int p_index) override; + void _set_joint_bone(int p_index, int p_joint, int p_bone); virtual void _process_ik(Skeleton3D *p_skeleton, double p_delta) override; @@ -250,9 +251,7 @@ public: float get_end_bone_length(int p_index) const; // Individual joints. - void set_joint_bone_name(int p_index, int p_joint, const String &p_bone_name); String get_joint_bone_name(int p_index, int p_joint) const; - void set_joint_bone(int p_index, int p_joint, int p_bone); int get_joint_bone(int p_index, int p_joint) const; void set_joint_count(int p_index, int p_count); diff --git a/scene/3d/ik_modifier_3d.cpp b/scene/3d/ik_modifier_3d.cpp index 2ec5c00e73..eba186ee49 100644 --- a/scene/3d/ik_modifier_3d.cpp +++ b/scene/3d/ik_modifier_3d.cpp @@ -160,7 +160,7 @@ Quaternion IKModifier3D::get_local_pose_rotation(Skeleton3D *p_skeleton, int p_b } Vector3 IKModifier3D::get_bone_axis(Skeleton3D *p_skeleton, int p_end_bone, BoneDirection p_direction, bool p_mutable_bone_axes) { - if (!p_skeleton->is_inside_tree()) { + if (!p_skeleton || !p_skeleton->is_inside_tree()) { return Vector3(); } Vector3 axis; diff --git a/scene/3d/limit_angular_velocity_modifier_3d.cpp b/scene/3d/limit_angular_velocity_modifier_3d.cpp index 89008a3902..e0dc3e94ca 100644 --- a/scene/3d/limit_angular_velocity_modifier_3d.cpp +++ b/scene/3d/limit_angular_velocity_modifier_3d.cpp @@ -58,9 +58,8 @@ bool LimitAngularVelocityModifier3D::_get(const StringName &p_path, Variant &r_r if (path.begins_with("chains/")) { int which = path.get_slicec('/', 1).to_int(); - String what = path.get_slicec('/', 2); ERR_FAIL_INDEX_V(which, (int)chains.size(), false); - + String what = path.get_slicec('/', 2); if (what == "root_bone_name") { r_ret = get_root_bone_name(which); } else if (what == "root_bone") { @@ -75,10 +74,12 @@ bool LimitAngularVelocityModifier3D::_get(const StringName &p_path, Variant &r_r } if (path.begins_with("joints/")) { int which = path.get_slicec('/', 1).to_int(); + ERR_FAIL_INDEX_V(which, (int)joints.size(), false); String what = path.get_slicec('/', 2); - ERR_FAIL_COND_V(!joints.has(which), false); if (what == "bone_name") { - r_ret = _get_joint_bone_name(which); + r_ret = get_joint_bone_name(which); + } else if (what == "bone") { + r_ret = get_joint_bone(which); } else { return false; } @@ -101,9 +102,10 @@ void LimitAngularVelocityModifier3D::_get_property_list(List *p_li p_list->push_back(PropertyInfo(Variant::INT, path + "end_bone", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); } - for (const KeyValue &E : joints) { - String path = "joints/" + itos(E.key) + "/"; + for (uint32_t i = 0; i < joints.size(); i++) { + String path = "joints/" + itos(i) + "/"; p_list->push_back(PropertyInfo(Variant::STRING, path + "bone_name", PROPERTY_HINT_ENUM_SUGGESTION, enum_hint, PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY)); + p_list->push_back(PropertyInfo(Variant::INT, path + "bone", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_READ_ONLY)); } } @@ -191,7 +193,6 @@ void LimitAngularVelocityModifier3D::set_end_bone(int p_index, int p_bone) { if (changed) { _make_joints_dirty(); } - notify_property_list_changed(); } int LimitAngularVelocityModifier3D::get_end_bone(int p_index) const { @@ -203,7 +204,6 @@ void LimitAngularVelocityModifier3D::set_chain_count(int p_count) { ERR_FAIL_COND(p_count < 0); chains.resize(p_count); _make_joints_dirty(); - notify_property_list_changed(); } int LimitAngularVelocityModifier3D::get_chain_count() const { @@ -214,9 +214,14 @@ void LimitAngularVelocityModifier3D::clear_chains() { set_chain_count(0); } -String LimitAngularVelocityModifier3D::_get_joint_bone_name(int p_bone) const { - ERR_FAIL_COND_V(!joints.has(p_bone), String()); - return joints[p_bone]; +String LimitAngularVelocityModifier3D::get_joint_bone_name(int p_index) const { + ERR_FAIL_INDEX_V(p_index, (int)joints.size(), String()); + return joints[p_index].name; +} + +int LimitAngularVelocityModifier3D::get_joint_bone(int p_index) const { + ERR_FAIL_INDEX_V(p_index, (int)joints.size(), -1); + return joints[p_index].bone; } int LimitAngularVelocityModifier3D::_get_joint_count() const { @@ -305,6 +310,17 @@ void LimitAngularVelocityModifier3D::_make_joints_dirty() { callable_mp(this, &LimitAngularVelocityModifier3D::_update_joints).call_deferred(); } +bool LimitAngularVelocityModifier3D::_is_joint_contained(int p_bone) { + bool ret = false; + for (const BoneJoint &joint : joints) { + if (joint.bone == p_bone) { + ret = true; + break; + } + } + return ret; +} + void LimitAngularVelocityModifier3D::_update_joints() { joints.clear(); bones.clear(); @@ -312,6 +328,7 @@ void LimitAngularVelocityModifier3D::_update_joints() { Skeleton3D *sk = get_skeleton(); if (!sk) { joints_dirty = false; + notify_property_list_changed(); return; } @@ -334,7 +351,7 @@ void LimitAngularVelocityModifier3D::_update_joints() { current_bone = sk->get_bone_parent(current_bone); } if (!valid) { - ERR_FAIL_EDMSG("Chains[" + itos(i) + "]: End bone must be the same as or a child of root bone."); + ERR_PRINT_ED("Chains[" + itos(i) + "]: End bone must be the same as or a child of root bone."); continue; } current_bone = cn.end_bone.bone; @@ -343,17 +360,21 @@ void LimitAngularVelocityModifier3D::_update_joints() { current_bone = sk->get_bone_parent(current_bone); } tmp_joints.push_back(current_bone); + tmp_joints.reverse(); for (uint32_t j = 0; j < tmp_joints.size(); j++) { int bn = tmp_joints[j]; - if (!joints.has(bn)) { - joints.insert(bn, sk->get_bone_name(bn)); + if (!_is_joint_contained(bn)) { + BoneJoint bj; + bj.bone = bn; + bj.name = sk->get_bone_name(bn); + joints.push_back(bj); } } } if (exclude) { for (int b = 0; b < sk->get_bone_count(); b++) { - if (joints.has(b)) { + if (_is_joint_contained(b)) { continue; } BoneRot br; @@ -362,16 +383,18 @@ void LimitAngularVelocityModifier3D::_update_joints() { bones.push_back(br); } } else { - for (const KeyValue &E : joints) { + for (const BoneJoint &E : joints) { BoneRot br; - br.first = E.key; - br.second = sk->get_bone_pose_rotation(E.key); + br.first = E.bone; + br.second = sk->get_bone_pose_rotation(E.bone); bones.push_back(br); } } joints_dirty = false; reset(); + + notify_property_list_changed(); } void LimitAngularVelocityModifier3D::_process_modification(double p_delta) { diff --git a/scene/3d/limit_angular_velocity_modifier_3d.h b/scene/3d/limit_angular_velocity_modifier_3d.h index 21c0ee3518..b5c6f42a67 100644 --- a/scene/3d/limit_angular_velocity_modifier_3d.h +++ b/scene/3d/limit_angular_velocity_modifier_3d.h @@ -53,7 +53,7 @@ private: double max_angular_velocity = Math::TAU; LocalVector chains; - RBMap joints; + LocalVector joints; LocalVector bones; bool joints_dirty = false; @@ -76,9 +76,9 @@ protected: void _make_joints_dirty(); void _update_joints(); + bool _is_joint_contained(int p_bone); // For editor. - String _get_joint_bone_name(int p_bone) const; int _get_joint_count() const; virtual void _process_modification(double p_delta) override; @@ -94,6 +94,9 @@ public: void set_end_bone(int p_index, int p_bone); int get_end_bone(int p_index) const; + String get_joint_bone_name(int p_index) const; + int get_joint_bone(int p_index) const; + void set_chain_count(int p_count); int get_chain_count() const; void clear_chains(); diff --git a/scene/3d/spring_bone_simulator_3d.cpp b/scene/3d/spring_bone_simulator_3d.cpp index 8d4a944330..4d97752226 100644 --- a/scene/3d/spring_bone_simulator_3d.cpp +++ b/scene/3d/spring_bone_simulator_3d.cpp @@ -121,11 +121,7 @@ bool SpringBoneSimulator3D::_set(const StringName &p_path, const Variant &p_valu } else if (what == "joints") { int idx = path.get_slicec('/', 3).to_int(); String prop = path.get_slicec('/', 4); - if (prop == "bone_name") { - set_joint_bone_name(which, idx, p_value); - } else if (prop == "bone") { - set_joint_bone(which, idx, p_value); - } else if (prop == "rotation_axis") { + if (prop == "rotation_axis") { set_joint_rotation_axis(which, idx, static_cast((int)p_value)); } else if (prop == "rotation_axis_vector") { set_joint_rotation_axis_vector(which, idx, p_value); @@ -321,7 +317,7 @@ void SpringBoneSimulator3D::_get_property_list(List *p_list) const for (uint32_t j = 0; j < settings[i]->joints.size(); j++) { String joint_path = path + "joints/" + itos(j) + "/"; props.push_back(PropertyInfo(Variant::STRING, joint_path + "bone_name", PROPERTY_HINT_ENUM_SUGGESTION, enum_hint, PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY)); - props.push_back(PropertyInfo(Variant::INT, joint_path + "bone", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_READ_ONLY)); + props.push_back(PropertyInfo(Variant::INT, joint_path + "bone", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_READ_ONLY)); props.push_back(PropertyInfo(Variant::INT, joint_path + "rotation_axis", PROPERTY_HINT_ENUM, SkeletonModifier3D::get_hint_rotation_axis())); props.push_back(PropertyInfo(Variant::VECTOR3, joint_path + "rotation_axis_vector")); props.push_back(PropertyInfo(Variant::FLOAT, joint_path + "radius", PROPERTY_HINT_RANGE, "0,1,0.001,or_greater,suffix:m")); @@ -883,18 +879,6 @@ bool SpringBoneSimulator3D::is_config_individual(int p_index) const { return settings[p_index]->individual_config; } -void SpringBoneSimulator3D::set_joint_bone_name(int p_index, int p_joint, const String &p_bone_name) { - // Exists only for indicate bone name on the inspector, no needs to make dirty joint array. - ERR_FAIL_INDEX(p_index, (int)settings.size()); - const LocalVector &joints = settings[p_index]->joints; - ERR_FAIL_INDEX(p_joint, (int)joints.size()); - joints[p_joint]->bone_name = p_bone_name; - Skeleton3D *sk = get_skeleton(); - if (sk) { - set_joint_bone(p_index, p_joint, sk->find_bone(joints[p_joint]->bone_name)); - } -} - String SpringBoneSimulator3D::get_joint_bone_name(int p_index, int p_joint) const { ERR_FAIL_INDEX_V(p_index, (int)settings.size(), String()); const LocalVector &joints = settings[p_index]->joints; @@ -902,7 +886,7 @@ String SpringBoneSimulator3D::get_joint_bone_name(int p_index, int p_joint) cons return joints[p_joint]->bone_name; } -void SpringBoneSimulator3D::set_joint_bone(int p_index, int p_joint, int p_bone) { +void SpringBoneSimulator3D::_set_joint_bone(int p_index, int p_joint, int p_bone) { ERR_FAIL_INDEX(p_index, (int)settings.size()); const LocalVector &joints = settings[p_index]->joints; ERR_FAIL_INDEX(p_joint, (int)joints.size()); @@ -1570,7 +1554,7 @@ void SpringBoneSimulator3D::_update_joint_array(int p_index) { set_joint_count(p_index, new_joints.size()); for (uint32_t i = 0; i < new_joints.size(); i++) { - set_joint_bone(p_index, i, new_joints[i]); + _set_joint_bone(p_index, i, new_joints[i]); } } diff --git a/scene/3d/spring_bone_simulator_3d.h b/scene/3d/spring_bone_simulator_3d.h index 97322eeb51..1b1cd327f7 100644 --- a/scene/3d/spring_bone_simulator_3d.h +++ b/scene/3d/spring_bone_simulator_3d.h @@ -180,6 +180,7 @@ protected: void _update_joint_array(int p_index); void _update_joints(bool p_reset); + void _set_joint_bone(int p_index, int p_joint, int p_bone); void _update_bone_axis(Skeleton3D *p_skeleton, SpringBone3DSetting *p_setting); @@ -267,9 +268,7 @@ public: void set_individual_config(int p_index, bool p_enabled); bool is_config_individual(int p_index) const; - void set_joint_bone_name(int p_index, int p_joint, const String &p_bone_name); String get_joint_bone_name(int p_index, int p_joint) const; - void set_joint_bone(int p_index, int p_joint, int p_bone); int get_joint_bone(int p_index, int p_joint) const; void set_joint_rotation_axis(int p_index, int p_joint, RotationAxis p_axis);