Repository: godotengine/godot
File: editor/scene/3d/skeleton_3d_editor_plugin.cpp (C++)

Code before:
			Skeleton3D *skeleton = se->get_skeleton();
			if (skeleton) {
				real_t grab_threshold = 8 * EDSCALE;
				Vector3 ray_from = p_camera->get_global_transform().origin;
				Transform3D gt = skeleton->get_global_transform();
				int closest_idx = -1;
				real_t closest_dist = 1e10;
				const int bone_count = skeleton->get_bone_count();
				for (int i = 0; i < bone_count; i++) {
					Vector3 joint_pos_3d = gt.xform(skeleton->get_bone_global_pose(i).origin);
					Vector2 joint_pos_2d = p_camera->unproject_position(joint_pos_3d);
					real_t dist_3d = ray_from.distance_to(joint_pos_3d);
					real_t dist_2d = mb->get_position().distance_to(joint_pos_2d);
					if (dist_2d < grab_threshold && dist_3d < closest_dist) {
						closest_dist = dist_3d;
						closest_idx = i;
					}
				}

				if (closest_idx >= 0) {
					se->select_bone(closest_idx);
					se->update_bone_original();

					Vector<Ref<Node3DGizmo>> gizmos = skeleton->get_gizmos();
					for (int i = 0; i < gizmos.size(); i++) {
						Ref<EditorNode3DGizmo> seg = gizmos[i];
						if (seg.is_valid()) {
							Transform3D bone_xform = seg->get_subgizmo_transform(closest_idx);
							ne->call("_set_subgizmo_selection", skeleton, seg, closest_idx, bone_xform);
							break;
						}
					}
					return EditorPlugin::AFTER_GUI_INPUT_STOP;
				}
			}
		}
		if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT) {
			if (ne->get_tool_mode() != Node3DEditor::TOOL_MODE_SELECT) {
				if (!ne->is_gizmo_visible()) {
					return EditorPlugin::AFTER_GUI_INPUT_STOP;
				}
			}
		}
		return EditorPlugin::AFTER_GUI_INPUT_CUSTOM;
	}
	return EditorPlugin::AFTER_GUI_INPUT_PASS;
}

bool Skeleton3DEditorPlugin::handles(Object *p_object) const {
	return p_object->is_class("Skeleton3D");
}

Review comment (suggestion):
```suggestion
					for (Ref<EditorNode3DGizmo> seg : gizmos) {
```

Code after:
			Skeleton3D *skeleton = se->get_skeleton();
			if (skeleton) {
				int closest_idx = Skeleton3DGizmoPlugin::skeleton_intersect_ray(skeleton, p_camera, mb->get_position());
				if (closest_idx >= 0) {
					se->select_bone(closest_idx);
					se->update_bone_original();

					Vector<Ref<Node3DGizmo>> gizmos = skeleton->get_gizmos();
					for (Ref<EditorNode3DGizmo> seg : gizmos) {
						if (seg.is_valid()) {
							Transform3D bone_xform = seg->get_subgizmo_transform(closest_idx);
							ne->call("_set_subgizmo_selection", skeleton, seg, closest_idx, bone_xform);
							break;
						}
					}
					return EditorPlugin::AFTER_GUI_INPUT_STOP;
				}
			}
		}
		if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT) {
			if (ne->get_tool_mode() != Node3DEditor::TOOL_MODE_SELECT) {
				if (!ne->is_gizmo_visible()) {
					return EditorPlugin::AFTER_GUI_INPUT_STOP;
				}
			}
		}
		return EditorPlugin::AFTER_GUI_INPUT_CUSTOM;
	}
	return EditorPlugin::AFTER_GUI_INPUT_PASS;
}

bool Skeleton3DEditorPlugin::handles(Object *p_object) const {
	return p_object->is_class("Skeleton3D");
}

void Skeleton3DEditor::_bone_enabled_changed(const int p_bone_id) {
	_update_gizmo_visible();
}

void Skeleton3DEditor::_update_gizmo_visible() {
	if (!skeleton) {
		return;
	}

	_subgizmo_selection_change();
	if (edit_mode) {
		if (selected_bone == -1) {
			skeleton->set_transform_gizmo_visible(false);
		} else {
			if (skeleton->is_bone_enabled(selected_bone) && !skeleton->is_show_rest_only()) {
				skeleton->set_transform_gizmo_visible(true);