From 9c3a1c00c4b309d52a1e973e7fcc1ae99d7de991 Mon Sep 17 00:00:00 2001 From: "Silc Lizard (Tokage) Renew" <61938263+TokageItLab@users.noreply.github.com> Date: Sun, 31 Mar 2024 03:49:15 +0900 Subject: [PATCH] Add tips detection to bone mapper Co-authored-by: Lyuma --- editor/plugins/bone_map_editor_plugin.cpp | 75 +++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/editor/plugins/bone_map_editor_plugin.cpp b/editor/plugins/bone_map_editor_plugin.cpp index e67f3bd5968..2bf9ad9e097 100644 --- a/editor/plugins/bone_map_editor_plugin.cpp +++ b/editor/plugins/bone_map_editor_plugin.cpp @@ -861,6 +861,8 @@ void BoneMapper::auto_mapping_process(Ref &p_bone_map) { picklist.clear(); // 4-1. Guess Finger + int tips_index = -1; + bool thumb_tips_size = 0; bool named_finger_is_found = false; LocalVector fingers; fingers.push_back("thumb|pollex"); @@ -894,6 +896,33 @@ void BoneMapper::auto_mapping_process(Ref &p_bone_map) { search_path.push_back(finger); finger = skeleton->get_bone_parent(finger); } + // Tips detection by name matching with "distal" from root. + for (int j = search_path.size() - 1; j >= 0; j--) { + if (RegEx("distal").search(skeleton->get_bone_name(search_path[j]).to_lower()).is_valid()) { + tips_index = j - 1; + break; + } + } + // Tips detection by name matching with "tip|leaf" from end. + if (tips_index < 0) { + for (int j = 0; j < search_path.size(); j++) { + if (RegEx("tip|leaf").search(skeleton->get_bone_name(search_path[j]).to_lower()).is_valid()) { + tips_index = j; + break; + } + } + } + // Tips detection by thumb children size. + if (tips_index < 0) { + if (i == 0) { + thumb_tips_size = MAX(0, search_path.size() - 3); + } + tips_index = thumb_tips_size - 1; + } + // Remove tips. + for (int j = 0; j <= tips_index; j++) { + search_path.remove_at(0); + } search_path.reverse(); if (search_path.size() == 1) { p_bone_map->_set_skeleton_bone_name(left_fingers_map[i][0], skeleton->get_bone_name(search_path[0])); @@ -941,6 +970,14 @@ void BoneMapper::auto_mapping_process(Ref &p_bone_map) { } } search_path.push_back(finger_root); + // Tips detection by thumb children size. + if (i == 0) { + thumb_tips_size = MAX(0, search_path.size() - 3); + } + tips_index = thumb_tips_size - 1; + for (int j = 0; j <= tips_index; j++) { + search_path.remove_at(0); + } search_path.reverse(); if (search_path.size() == 1) { p_bone_map->_set_skeleton_bone_name(left_fingers_map[i][0], skeleton->get_bone_name(search_path[0])); @@ -958,6 +995,9 @@ void BoneMapper::auto_mapping_process(Ref &p_bone_map) { picklist.clear(); } } + + tips_index = -1; + thumb_tips_size = 0; named_finger_is_found = false; if (right_hand_or_palm != -1) { LocalVector> right_fingers_map; @@ -985,6 +1025,33 @@ void BoneMapper::auto_mapping_process(Ref &p_bone_map) { search_path.push_back(finger); finger = skeleton->get_bone_parent(finger); } + // Tips detection by name matching with "distal" from root. + for (int j = search_path.size() - 1; j >= 0; j--) { + if (RegEx("distal").search(skeleton->get_bone_name(search_path[j]).to_lower()).is_valid()) { + tips_index = j - 1; + break; + } + } + // Tips detection by name matching with "tip|leaf" from end. + if (tips_index < 0) { + for (int j = 0; j < search_path.size(); j++) { + if (RegEx("tip|leaf").search(skeleton->get_bone_name(search_path[j]).to_lower()).is_valid()) { + tips_index = j; + break; + } + } + } + // Tips detection by thumb children size. + if (tips_index < 0) { + if (i == 0) { + thumb_tips_size = MAX(0, search_path.size() - 3); + } + tips_index = thumb_tips_size - 1; + } + // Remove tips. + for (int j = 0; j <= tips_index; j++) { + search_path.remove_at(0); + } search_path.reverse(); if (search_path.size() == 1) { p_bone_map->_set_skeleton_bone_name(right_fingers_map[i][0], skeleton->get_bone_name(search_path[0])); @@ -1032,6 +1099,14 @@ void BoneMapper::auto_mapping_process(Ref &p_bone_map) { } } search_path.push_back(finger_root); + // Tips detection by thumb children size. + if (i == 0) { + thumb_tips_size = MAX(0, search_path.size() - 3); + } + tips_index = thumb_tips_size - 1; + for (int j = 0; j <= tips_index; j++) { + search_path.remove_at(0); + } search_path.reverse(); if (search_path.size() == 1) { p_bone_map->_set_skeleton_bone_name(right_fingers_map[i][0], skeleton->get_bone_name(search_path[0]));