diff --git a/modules/many_bone_ik/doc_classes/IKBoneSegment3D.xml b/modules/many_bone_ik/doc_classes/IKBoneSegment3D.xml index 1ddf26131a36..8f5eda17737a 100644 --- a/modules/many_bone_ik/doc_classes/IKBoneSegment3D.xml +++ b/modules/many_bone_ik/doc_classes/IKBoneSegment3D.xml @@ -7,7 +7,7 @@ - + diff --git a/modules/many_bone_ik/editor/many_bone_ik_3d_gizmo_plugin.cpp b/modules/many_bone_ik/editor/many_bone_ik_3d_gizmo_plugin.cpp index ce254010cf64..68292f4860d8 100644 --- a/modules/many_bone_ik/editor/many_bone_ik_3d_gizmo_plugin.cpp +++ b/modules/many_bone_ik/editor/many_bone_ik_3d_gizmo_plugin.cpp @@ -30,6 +30,7 @@ #include "many_bone_ik_3d_gizmo_plugin.h" +#include "core/variant/typed_array.h" #include "modules/many_bone_ik/src/ik_kusudama_3d.h" #include "core/io/resource_saver.h" @@ -97,8 +98,9 @@ void ManyBoneIK3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Vector bones_to_process = many_bone_ik_skeleton->get_parentless_bones(); int bones_to_process_i = 0; Vector processing_bones; - Vector> bone_segments = many_bone_ik->get_segmented_skeletons(); - for (Ref bone_segment : bone_segments) { + TypedArray bone_segments = many_bone_ik->get_child_segments(); + for (int32_t segment_i = 0; segment_i < bone_segments.size(); segment_i++) { + Ref bone_segment = bone_segments[segment_i]; if (bone_segment.is_null()) { continue; } @@ -113,7 +115,7 @@ void ManyBoneIK3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { } Color current_bone_color = bone_color; for (BoneId bone_i : bones_to_process) { - Ref ik_bone = bone_segment->get_ik_bone(bone_i); + Ref ik_bone = bone_segment->find_ik_bone(bone_i); if (ik_bone.is_null()) { continue; } diff --git a/modules/many_bone_ik/editor/many_bone_ik_3d_handle_gizmo_plugin.cpp b/modules/many_bone_ik/editor/many_bone_ik_3d_handle_gizmo_plugin.cpp index 08fb59be6b81..2f1da2e24ef2 100644 --- a/modules/many_bone_ik/editor/many_bone_ik_3d_handle_gizmo_plugin.cpp +++ b/modules/many_bone_ik/editor/many_bone_ik_3d_handle_gizmo_plugin.cpp @@ -97,8 +97,9 @@ void ManyBoneIK3DHandleGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Vector bones_to_process = many_bone_ik_skeleton->get_parentless_bones(); int bones_to_process_i = 0; Vector processing_bones; - Vector> bone_segments = many_bone_ik->get_segmented_skeletons(); - for (Ref bone_segment : bone_segments) { + TypedArray bone_segments = many_bone_ik->get_child_segments(); + for (int32_t segment_i = 0; segment_i < bone_segments.size(); segment_i++) { + Ref bone_segment = bone_segments[segment_i]; if (bone_segment.is_null()) { continue; } @@ -113,7 +114,7 @@ void ManyBoneIK3DHandleGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { } Color current_bone_color = bone_color; for (BoneId bone_i : bones_to_process) { - Ref ik_bone = bone_segment->get_ik_bone(bone_i); + Ref ik_bone = bone_segment->find_ik_bone(bone_i); if (ik_bone.is_null()) { continue; } diff --git a/modules/many_bone_ik/src/ik_bone_segment_3d.cpp b/modules/many_bone_ik/src/ik_bone_segment_3d.cpp index d60460fa8b16..3684e12634c9 100644 --- a/modules/many_bone_ik/src/ik_bone_segment_3d.cpp +++ b/modules/many_bone_ik/src/ik_bone_segment_3d.cpp @@ -30,6 +30,7 @@ #include "ik_bone_segment_3d.h" +#include "core/object/object.h" #include "ik_effector_3d.h" #include "ik_kusudama_3d.h" #include "ik_limit_cone_3d.h" @@ -37,7 +38,7 @@ #include "math/ik_node_3d.h" #include "scene/3d/skeleton_3d.h" -Ref IKBoneSegment3D::get_root() const { +Ref IKBoneSegment3D::get_root() { return root; } Ref IKBoneSegment3D::get_tip() const { @@ -49,7 +50,7 @@ bool IKBoneSegment3D::is_pinned() const { return tip->is_pinned(); } -Vector> IKBoneSegment3D::get_child_segments() const { +TypedArray IKBoneSegment3D::get_child_segments() const { return child_segments; } @@ -77,7 +78,12 @@ void IKBoneSegment3D::generate_default_segments_from_root(Vector next = Ref(memnew(IKBone3D(skeleton->get_bone_name(bone_id), skeleton, temp_tip, p_pins, p_many_bone_ik->get_default_damp(), p_many_bone_ik))); - root_segment->bone_map[bone_id] = next; + Ref root_segment; + Ref current_segment = Ref(this); + while (current_segment.is_valid()) { + root_segment = current_segment; + current_segment = current_segment->get_parent_segment(); + } temp_tip = next; } else { break; @@ -95,7 +101,8 @@ void IKBoneSegment3D::generate_default_segments_from_root(Vector> &p_list, bool p_recursive, bool p_debug_skeleton) const { if (p_recursive) { for (int32_t child_i = 0; child_i < child_segments.size(); child_i++) { - child_segments[child_i]->create_bone_list(p_list, p_recursive, p_debug_skeleton); + Ref segment = child_segments[child_i]; + segment->create_bone_list(p_list, p_recursive, p_debug_skeleton); } } Ref current_bone = tip; @@ -139,8 +146,9 @@ void IKBoneSegment3D::update_pinned_list(Vector> &r_weights) { effector_list.push_back(tip->get_pin()); } if (passthrough_factor > 0.0) { - for (Ref child : child_segments) { - effector_list.append_array(child->effector_list); + for (int32_t segment_i = 0; segment_i < child_segments.size(); segment_i++) { + Ref segment = child_segments[segment_i]; + effector_list.append_array(segment->effector_list); } } } @@ -262,7 +270,8 @@ void IKBoneSegment3D::update_tip_headings(Ref p_for_bone, PackedVector } void IKBoneSegment3D::segment_solver(const Vector &p_damp, float p_default_damp, bool p_constraint_mode) { - for (Ref child : child_segments) { + for (int32_t segment_i = 0; segment_i < child_segments.size(); segment_i++) { + Ref child = child_segments[segment_i]; if (child.is_null()) { continue; } @@ -295,7 +304,18 @@ void IKBoneSegment3D::qcp_solver(const Vector &p_damp, float p_default_da void IKBoneSegment3D::_bind_methods() { ClassDB::bind_method(D_METHOD("is_pinned"), &IKBoneSegment3D::is_pinned); - ClassDB::bind_method(D_METHOD("get_ik_bone", "bone"), &IKBoneSegment3D::get_ik_bone); + ClassDB::bind_method(D_METHOD("find_ik_bone", "bone"), &IKBoneSegment3D::find_ik_bone); + ClassDB::bind_method(D_METHOD("get_root"), &IKBoneSegment3D::get_root); + ClassDB::bind_method(D_METHOD("get_default_stabilizing_pass_count"), &IKBoneSegment3D::get_default_stabilizing_pass_count); + ClassDB::bind_method(D_METHOD("set_default_stabilizing_pass_count", "count"), &IKBoneSegment3D::set_default_stabilizing_pass_count); + ClassDB::bind_method(D_METHOD("set_child_segments", "segment"), &IKBoneSegment3D::set_child_segments); + ClassDB::bind_method(D_METHOD("get_child_segments"), &IKBoneSegment3D::get_child_segments); + ClassDB::bind_method(D_METHOD("set_parent_segment", "segment"), &IKBoneSegment3D::set_parent_segment); + ClassDB::bind_method(D_METHOD("get_parent_segment"), &IKBoneSegment3D::get_parent_segment); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "stabilizing_pass_count"), "set_default_stabilizing_pass_count", "get_default_stabilizing_pass_count"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "child_segments", PROPERTY_HINT_ARRAY_TYPE, "IKBoneSegment3D"), "set_child_segments", "get_child_segments"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "parent_segment", PROPERTY_HINT_RESOURCE_TYPE, "IKBoneSegment3D"), "set_parent_segment", "get_parent_segment"); } Ref IKBoneSegment3D::get_parent_segment() { @@ -304,16 +324,10 @@ Ref IKBoneSegment3D::get_parent_segment() { IKBoneSegment3D::IKBoneSegment3D(Skeleton3D *p_skeleton, StringName p_root_bone_name, Vector> &p_pins, ManyBoneIK3D *p_many_bone_ik, const Ref &p_parent, BoneId p_root, BoneId p_tip) { - root = p_root; tip = p_tip; skeleton = p_skeleton; root = Ref(memnew(IKBone3D(p_root_bone_name, p_skeleton, p_parent, p_pins, Math_PI, p_many_bone_ik))); - if (p_parent.is_valid()) { - root_segment = p_parent->root_segment; - } else { - root_segment = Ref(this); - } - root_segment->bone_map[root->get_bone_id()] = root; + if (p_parent.is_valid()) { parent_segment = p_parent; root->set_parent(p_parent->get_tip()); @@ -332,11 +346,19 @@ Vector> IKBoneSegment3D::get_bone_list() const { return bones; } -Ref IKBoneSegment3D::get_ik_bone(BoneId p_bone) const { - if (!bone_map.has(p_bone)) { - return Ref(); +Ref IKBoneSegment3D::find_ik_bone(BoneId p_bone) const { + Ref root_segment; + Ref current_segment = Ref(this); + while (current_segment.is_valid()) { + root_segment = current_segment; + current_segment = current_segment->get_parent_segment(); + } + for (Ref current_bone : root_segment->bones) { + if (current_bone->get_bone_id() == p_bone) { + return current_bone; + } } - return bone_map[p_bone]; + return Ref(); } void IKBoneSegment3D::create_headings_arrays() { @@ -412,7 +434,9 @@ void IKBoneSegment3D::recursive_create_penalty_array(Ref p_bone r_pinned_bones.push_back(current_tip); current_falloff = pin->get_passthrough_factor(); } - for (Ref s : p_bone_segment->get_child_segments()) { + TypedArray bone_segments = p_bone_segment->get_child_segments(); + for (int32_t segment_i = 0; segment_i < bone_segments.size(); segment_i++) { + Ref s = bone_segments[segment_i]; recursive_create_penalty_array(s, r_penalty_array, r_pinned_bones, p_falloff * current_falloff); } } @@ -420,7 +444,29 @@ void IKBoneSegment3D::recursive_create_penalty_array(Ref p_bone void IKBoneSegment3D::recursive_create_headings_arrays_for(Ref p_bone_segment) { p_bone_segment->create_headings_arrays(); - for (Ref segments : p_bone_segment->get_child_segments()) { - recursive_create_headings_arrays_for(segments); + TypedArray segments = p_bone_segment->get_child_segments(); + for (int32_t segment_i = 0; segment_i < segments.size(); segment_i++) { + Ref segment = segments[segment_i]; + recursive_create_headings_arrays_for(segment); } } + +void IKBoneSegment3D::set_child_segments(TypedArray p_child_segments) { + child_segments = p_child_segments; +} + +void IKBoneSegment3D::set_default_stabilizing_pass_count(int32_t p_count) { + default_stabilizing_pass_count = p_count; +} + +int32_t IKBoneSegment3D::get_default_stabilizing_pass_count() { + return default_stabilizing_pass_count; +} + +void IKBoneSegment3D::set_tip(Ref p_tip) { + tip = p_tip; +} + +void IKBoneSegment3D::set_parent_segment(Ref p_parent_segment) { + parent_segment = p_parent_segment; +} diff --git a/modules/many_bone_ik/src/ik_bone_segment_3d.h b/modules/many_bone_ik/src/ik_bone_segment_3d.h index 75bccc61a9cc..b1476b100048 100644 --- a/modules/many_bone_ik/src/ik_bone_segment_3d.h +++ b/modules/many_bone_ik/src/ik_bone_segment_3d.h @@ -50,9 +50,8 @@ class IKBoneSegment3D : public Resource { Ref tip; Vector> bones; Vector> pinned_bones; - Vector> child_segments; // Contains only direct child chains that end with effectors or have child that end with effectors + TypedArray child_segments; // Contains only direct child chains that end with effectors or have child that end with effectors Ref parent_segment; - Ref root_segment; Vector> effector_list; PackedVector3Array target_headings; PackedVector3Array tip_headings; @@ -72,12 +71,14 @@ class IKBoneSegment3D : public Resource { void qcp_solver(const Vector &p_damp, float p_default_damp, bool p_translate, bool p_constraint_mode); void update_optimal_rotation(Ref p_for_bone, real_t p_damp, bool p_translate, bool p_constraint_mode); float get_manual_msd(const PackedVector3Array &r_htip, const PackedVector3Array &r_htarget, const Vector &p_weights); - HashMap> bone_map; protected: static void _bind_methods(); public: + Ref get_root(); + int32_t get_default_stabilizing_pass_count(); + void set_default_stabilizing_pass_count(int32_t p_count); const double evec_prec = static_cast(1E-6); const double eval_prec = static_cast(1E-11); static Quaternion clamp_to_quadrance_angle(Quaternion p_quat, real_t p_cos_half_angle); @@ -85,14 +86,19 @@ class IKBoneSegment3D : public Resource { void create_headings_arrays(); void recursive_create_penalty_array(Ref p_bone_segment, Vector> &r_penalty_array, Vector> &r_pinned_bones, real_t p_falloff); Ref get_parent_segment(); + void set_parent_segment(Ref p_parent_segment); void segment_solver(const Vector &p_damp, float p_default_damp, bool p_constraint_mode); - Ref get_root() const; Ref get_tip() const; + void set_tip(Ref p_tip); bool is_pinned() const; - Vector> get_child_segments() const; + TypedArray get_child_segments() const; + void set_child_segments(TypedArray p_child_segments); void create_bone_list(Vector> &p_list, bool p_recursive = false, bool p_debug_skeleton = false) const; Vector> get_bone_list() const; - Ref get_ik_bone(BoneId p_bone) const; + void set_bone_list(Vector> p_bone_list) { + bones = p_bone_list; + } + Ref find_ik_bone(BoneId p_bone) const; void generate_default_segments_from_root(Vector> &p_pins, BoneId p_root_bone, BoneId p_tip_bone, ManyBoneIK3D *p_many_bone_ik); void update_pinned_list(Vector> &r_weights); IKBoneSegment3D() {} diff --git a/modules/many_bone_ik/src/ik_effector_3d.cpp b/modules/many_bone_ik/src/ik_effector_3d.cpp index ecf35677031d..ad5abeb2ea50 100644 --- a/modules/many_bone_ik/src/ik_effector_3d.cpp +++ b/modules/many_bone_ik/src/ik_effector_3d.cpp @@ -57,7 +57,7 @@ bool IKEffector3D::get_target_node_rotation() const { return use_target_node_rotation; } -Ref IKEffector3D::get_ik_bone_3d() const { +Ref IKEffector3D::find_ik_bone_3d() const { return for_bone; } diff --git a/modules/many_bone_ik/src/ik_effector_3d.h b/modules/many_bone_ik/src/ik_effector_3d.h index 7f99d9c06bec..10e4c0c5a7e8 100644 --- a/modules/many_bone_ik/src/ik_effector_3d.h +++ b/modules/many_bone_ik/src/ik_effector_3d.h @@ -80,7 +80,7 @@ class IKEffector3D : public Resource { Transform3D get_target_global_transform() const; void set_target_node_rotation(bool p_use); bool get_target_node_rotation() const; - Ref get_ik_bone_3d() const; + Ref find_ik_bone_3d() const; bool is_following_translation_only() const; int32_t update_effector_target_headings(PackedVector3Array *p_headings, int32_t p_index, Ref p_for_bone, const Vector *p_weights) const; int32_t update_effector_tip_headings(PackedVector3Array *p_headings, int32_t p_index, Ref p_for_bone, bool p_is_uniform) const; diff --git a/modules/many_bone_ik/src/many_bone_ik_3d.cpp b/modules/many_bone_ik/src/many_bone_ik_3d.cpp index 651196e00c81..3cd1040d1db8 100644 --- a/modules/many_bone_ik/src/many_bone_ik_3d.cpp +++ b/modules/many_bone_ik/src/many_bone_ik_3d.cpp @@ -30,8 +30,9 @@ #include "many_bone_ik_3d.h" #include "core/core_string_names.h" -#include "core/error/error_macros.h" +#include "core/variant/typed_array.h" #include "ik_bone_3d.h" +#include "ik_bone_segment_3d.h" #include "ik_kusudama_3d.h" #ifdef TOOLS_ENABLED @@ -477,7 +478,10 @@ void ManyBoneIK3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_ui_selected_bone"), &ManyBoneIK3D::get_ui_selected_bone); ClassDB::bind_method(D_METHOD("set_filter_bones", "bones"), &ManyBoneIK3D::set_filter_bones); ClassDB::bind_method(D_METHOD("get_filter_bones"), &ManyBoneIK3D::get_filter_bones); + ClassDB::bind_method(D_METHOD("set_child_segments", "segments"), &ManyBoneIK3D::set_child_segments); + ClassDB::bind_method(D_METHOD("get_child_segments"), &ManyBoneIK3D::get_child_segments); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "child_segments", PROPERTY_HINT_ARRAY_TYPE, "IKBoneSegment3D"), "set_child_segments", "get_child_segments"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton_node_path"), "set_skeleton_node_path", "get_skeleton_node_path"); ADD_PROPERTY(PropertyInfo(Variant::INT, "iterations_per_frame", PROPERTY_HINT_RANGE, "1,150,1,or_greater"), "set_iterations_per_frame", "get_iterations_per_frame"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "default_damp", PROPERTY_HINT_RANGE, "0.01,180.0,0.01,radians,exp", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_default_damp", "get_default_damp"); @@ -671,9 +675,6 @@ void ManyBoneIK3D::_set_constraint_name(int32_t p_index, String p_name) { set_dirty(); } -Vector> ManyBoneIK3D::get_segmented_skeletons() { - return segmented_skeletons; -} float ManyBoneIK3D::get_iterations_per_frame() const { return iterations_per_frame; } @@ -743,7 +744,9 @@ void ManyBoneIK3D::execute(real_t delta) { } update_ik_bones_transform(); for (int32_t i = 0; i < get_iterations_per_frame(); i++) { - for (Ref segmented_skeleton : segmented_skeletons) { + TypedArray segments = segmented_skeletons; + for (int32_t segment_i = 0; segment_i < segments.size(); segment_i++) { + Ref segmented_skeleton = segments[segment_i]; if (segmented_skeleton.is_null()) { continue; } @@ -956,12 +959,22 @@ Vector> ManyBoneIK3D::get_bone_list() { void ManyBoneIK3D::set_bone_direction_transform(int32_t p_index, Transform3D p_transform) { ERR_FAIL_INDEX(p_index, constraint_names.size()); + + if (!segmented_skeletons.size()) { + return; + } + if (!get_skeleton()) { + return; + } String bone_name = constraint_names[p_index]; - for (Ref segmented_skeleton : segmented_skeletons) { + + TypedArray segments = segmented_skeletons; + for (int32_t segment_i = 0; segment_i < segments.size(); segment_i++) { + Ref segmented_skeleton = segments[segment_i]; if (segmented_skeleton.is_null()) { continue; } - Ref ik_bone = segmented_skeleton->get_ik_bone(get_skeleton()->find_bone(bone_name)); + Ref ik_bone = segmented_skeleton->find_ik_bone(get_skeleton()->find_bone(bone_name)); if (ik_bone.is_null()) { continue; } @@ -982,11 +995,13 @@ Transform3D ManyBoneIK3D::get_bone_direction_transform(int32_t p_index) const { if (!get_skeleton()) { return Transform3D(); } - for (Ref segmented_skeleton : segmented_skeletons) { + TypedArray segments = segmented_skeletons; + for (int32_t segment_i = 0; segment_i < segments.size(); segment_i++) { + Ref segmented_skeleton = segments[segment_i]; if (segmented_skeleton.is_null()) { continue; } - Ref ik_bone = segmented_skeleton->get_ik_bone(get_skeleton()->find_bone(bone_name)); + Ref ik_bone = segmented_skeleton->find_ik_bone(get_skeleton()->find_bone(bone_name)); if (ik_bone.is_null()) { continue; } @@ -1007,11 +1022,13 @@ Transform3D ManyBoneIK3D::get_constraint_orientation_transform(int32_t p_index) if (!get_skeleton()) { return Transform3D(); } - for (Ref segmented_skeleton : segmented_skeletons) { + TypedArray segments = segmented_skeletons; + for (int32_t segment_i = 0; segment_i < segments.size(); segment_i++) { + Ref segmented_skeleton = segments[segment_i]; if (segmented_skeleton.is_null()) { continue; } - Ref ik_bone = segmented_skeleton->get_ik_bone(get_skeleton()->find_bone(bone_name)); + Ref ik_bone = segmented_skeleton->find_ik_bone(get_skeleton()->find_bone(bone_name)); if (ik_bone.is_null()) { continue; } @@ -1026,14 +1043,19 @@ Transform3D ManyBoneIK3D::get_constraint_orientation_transform(int32_t p_index) void ManyBoneIK3D::set_constraint_orientation_transform(int32_t p_index, Transform3D p_transform) { ERR_FAIL_INDEX(p_index, constraint_names.size()); String bone_name = constraint_names[p_index]; + if (!segmented_skeletons.size()) { + return; + } if (!get_skeleton()) { return; } - for (Ref segmented_skeleton : segmented_skeletons) { + TypedArray segments = segmented_skeletons; + for (int32_t segment_i = 0; segment_i < segments.size(); segment_i++) { + Ref segmented_skeleton = segments[segment_i]; if (segmented_skeleton.is_null()) { continue; } - Ref ik_bone = segmented_skeleton->get_ik_bone(get_skeleton()->find_bone(bone_name)); + Ref ik_bone = segmented_skeleton->find_ik_bone(get_skeleton()->find_bone(bone_name)); if (ik_bone.is_null()) { continue; } @@ -1054,11 +1076,13 @@ Transform3D ManyBoneIK3D::get_constraint_twist_transform(int32_t p_index) const if (!get_skeleton()) { return Transform3D(); } - for (Ref segmented_skeleton : segmented_skeletons) { + TypedArray segments = segmented_skeletons; + for (int32_t segment_i = 0; segment_i < segments.size(); segment_i++) { + Ref segmented_skeleton = segments[segment_i]; if (segmented_skeleton.is_null()) { continue; } - Ref ik_bone = segmented_skeleton->get_ik_bone(get_skeleton()->find_bone(bone_name)); + Ref ik_bone = segmented_skeleton->find_ik_bone(get_skeleton()->find_bone(bone_name)); if (ik_bone.is_null()) { continue; } @@ -1073,14 +1097,20 @@ Transform3D ManyBoneIK3D::get_constraint_twist_transform(int32_t p_index) const void ManyBoneIK3D::set_constraint_twist_transform(int32_t p_index, Transform3D p_transform) { ERR_FAIL_INDEX(p_index, constraint_names.size()); String bone_name = constraint_names[p_index]; + + if (!segmented_skeletons.size()) { + return; + } if (!get_skeleton()) { return; } - for (Ref segmented_skeleton : segmented_skeletons) { + TypedArray segments = segmented_skeletons; + for (int32_t segment_i = 0; segment_i < segments.size(); segment_i++) { + Ref segmented_skeleton = segments[segment_i]; if (segmented_skeleton.is_null()) { continue; } - Ref ik_bone = segmented_skeleton->get_ik_bone(get_skeleton()->find_bone(bone_name)); + Ref ik_bone = segmented_skeleton->find_ik_bone(get_skeleton()->find_bone(bone_name)); if (ik_bone.is_null()) { continue; } diff --git a/modules/many_bone_ik/src/many_bone_ik_3d.h b/modules/many_bone_ik/src/many_bone_ik_3d.h index 896dea68f0cc..fd5dbc33f9ca 100644 --- a/modules/many_bone_ik/src/many_bone_ik_3d.h +++ b/modules/many_bone_ik/src/many_bone_ik_3d.h @@ -49,7 +49,7 @@ class ManyBoneIK3D : public Node3D { private: bool is_constraint_mode = false; NodePath skeleton_path; - Vector> segmented_skeletons; + TypedArray segmented_skeletons; int32_t constraint_count = 0; Vector constraint_names; int32_t pin_count = 0; @@ -91,6 +91,13 @@ class ManyBoneIK3D : public Node3D { void _notification(int p_what); public: + void set_child_segments(TypedArray p_child_segments) { + segmented_skeletons = p_child_segments; + } + TypedArray get_child_segments() const { + return segmented_skeletons; + } + Transform3D get_godot_skeleton_transform_inverse() { return godot_skeleton_transform_inverse; } @@ -111,7 +118,6 @@ class ManyBoneIK3D : public Node3D { NodePath get_skeleton_node_path(); Skeleton3D *get_skeleton() const; Vector> get_bone_list(); - Vector> get_segmented_skeletons(); float get_iterations_per_frame() const; void set_iterations_per_frame(const float &p_iterations_per_frame); void queue_print_skeleton();