mirror of
				https://github.com/godotengine/godot.git
				synced 2025-11-03 23:21:15 +00:00 
			
		
		
		
	Merge pull request #96094 from SaracenOne/add_3d_skeleton_to_advanced_importer
Add 3D Skeleton Preview to Advanced Importer
This commit is contained in:
		
						commit
						82688e9e2e
					
				
					 4 changed files with 113 additions and 29 deletions
				
			
		| 
						 | 
					@ -37,6 +37,7 @@
 | 
				
			||||||
#include "editor/editor_settings.h"
 | 
					#include "editor/editor_settings.h"
 | 
				
			||||||
#include "editor/editor_string_names.h"
 | 
					#include "editor/editor_string_names.h"
 | 
				
			||||||
#include "editor/gui/editor_file_dialog.h"
 | 
					#include "editor/gui/editor_file_dialog.h"
 | 
				
			||||||
 | 
					#include "editor/plugins/skeleton_3d_editor_plugin.h"
 | 
				
			||||||
#include "editor/themes/editor_scale.h"
 | 
					#include "editor/themes/editor_scale.h"
 | 
				
			||||||
#include "scene/3d/importer_mesh_instance_3d.h"
 | 
					#include "scene/3d/importer_mesh_instance_3d.h"
 | 
				
			||||||
#include "scene/animation/animation_player.h"
 | 
					#include "scene/animation/animation_player.h"
 | 
				
			||||||
| 
						 | 
					@ -419,7 +420,9 @@ void SceneImportSettingsDialog::_fill_scene(Node *p_node, TreeItem *p_parent_ite
 | 
				
			||||||
				animation_player->connect(SceneStringName(animation_finished), callable_mp(this, &SceneImportSettingsDialog::_animation_finished));
 | 
									animation_player->connect(SceneStringName(animation_finished), callable_mp(this, &SceneImportSettingsDialog::_animation_finished));
 | 
				
			||||||
			} else if (Object::cast_to<Skeleton3D>(p_node)) {
 | 
								} else if (Object::cast_to<Skeleton3D>(p_node)) {
 | 
				
			||||||
				category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE;
 | 
									category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE;
 | 
				
			||||||
				skeletons.push_back(Object::cast_to<Skeleton3D>(p_node));
 | 
									Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_node);
 | 
				
			||||||
 | 
									skeleton->connect(SceneStringName(tree_entered), callable_mp(this, &SceneImportSettingsDialog::_skeleton_tree_entered).bind(skeleton));
 | 
				
			||||||
 | 
									skeletons.push_back(skeleton);
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_NODE;
 | 
									category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_NODE;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -480,6 +483,31 @@ void SceneImportSettingsDialog::_fill_scene(Node *p_node, TreeItem *p_parent_ite
 | 
				
			||||||
			contents_aabb.merge_with(aabb);
 | 
								contents_aabb.merge_with(aabb);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_node);
 | 
				
			||||||
 | 
						if (skeleton) {
 | 
				
			||||||
 | 
							Ref<ArrayMesh> bones_mesh = Skeleton3DGizmoPlugin::get_bones_mesh(skeleton, -1, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							bones_mesh_preview->set_mesh(bones_mesh);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Transform3D accum_xform;
 | 
				
			||||||
 | 
							Node3D *base = skeleton;
 | 
				
			||||||
 | 
							while (base) {
 | 
				
			||||||
 | 
								accum_xform = base->get_transform() * accum_xform;
 | 
				
			||||||
 | 
								base = Object::cast_to<Node3D>(base->get_parent());
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							bones_mesh_preview->set_transform(accum_xform * skeleton->get_transform());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							AABB aabb = accum_xform.xform(bones_mesh->get_aabb());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (first_aabb) {
 | 
				
			||||||
 | 
								contents_aabb = aabb;
 | 
				
			||||||
 | 
								first_aabb = false;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								contents_aabb.merge_with(aabb);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SceneImportSettingsDialog::_update_scene() {
 | 
					void SceneImportSettingsDialog::_update_scene() {
 | 
				
			||||||
| 
						 | 
					@ -795,6 +823,7 @@ void SceneImportSettingsDialog::_select(Tree *p_from, const String &p_type, cons
 | 
				
			||||||
	selecting = true;
 | 
						selecting = true;
 | 
				
			||||||
	scene_import_settings_data->hide_options = false;
 | 
						scene_import_settings_data->hide_options = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bones_mesh_preview->hide();
 | 
				
			||||||
	if (p_type == "Node") {
 | 
						if (p_type == "Node") {
 | 
				
			||||||
		node_selected->hide(); // Always hide just in case.
 | 
							node_selected->hide(); // Always hide just in case.
 | 
				
			||||||
		mesh_preview->hide();
 | 
							mesh_preview->hide();
 | 
				
			||||||
| 
						 | 
					@ -834,6 +863,7 @@ void SceneImportSettingsDialog::_select(Tree *p_from, const String &p_type, cons
 | 
				
			||||||
				scene_import_settings_data->category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE;
 | 
									scene_import_settings_data->category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE;
 | 
				
			||||||
			} else if (Object::cast_to<Skeleton3D>(nd.node)) {
 | 
								} else if (Object::cast_to<Skeleton3D>(nd.node)) {
 | 
				
			||||||
				scene_import_settings_data->category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE;
 | 
									scene_import_settings_data->category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE;
 | 
				
			||||||
 | 
									bones_mesh_preview->show();
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				scene_import_settings_data->category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_NODE;
 | 
									scene_import_settings_data->category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_NODE;
 | 
				
			||||||
				scene_import_settings_data->hide_options = editing_animation;
 | 
									scene_import_settings_data->hide_options = editing_animation;
 | 
				
			||||||
| 
						 | 
					@ -853,6 +883,8 @@ void SceneImportSettingsDialog::_select(Tree *p_from, const String &p_type, cons
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		scene_import_settings_data->settings = &ad.settings;
 | 
							scene_import_settings_data->settings = &ad.settings;
 | 
				
			||||||
		scene_import_settings_data->category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_ANIMATION;
 | 
							scene_import_settings_data->category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_ANIMATION;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							_animation_update_skeleton_visibility();
 | 
				
			||||||
	} else if (p_type == "Mesh") {
 | 
						} else if (p_type == "Mesh") {
 | 
				
			||||||
		node_selected->hide();
 | 
							node_selected->hide();
 | 
				
			||||||
		if (Object::cast_to<Node3D>(scene)) {
 | 
							if (Object::cast_to<Node3D>(scene)) {
 | 
				
			||||||
| 
						 | 
					@ -1055,6 +1087,11 @@ void SceneImportSettingsDialog::_animation_slider_value_changed(double p_value)
 | 
				
			||||||
	animation_player->seek(p_value * animation_map[selected_id].animation->get_length(), true);
 | 
						animation_player->seek(p_value * animation_map[selected_id].animation->get_length(), true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SceneImportSettingsDialog::_skeleton_tree_entered(Skeleton3D *p_skeleton) {
 | 
				
			||||||
 | 
						bones_mesh_preview->set_skeleton_path(p_skeleton->get_path());
 | 
				
			||||||
 | 
						bones_mesh_preview->set_skin(p_skeleton->register_skin(p_skeleton->create_skin_from_rest_transforms()));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SceneImportSettingsDialog::_animation_finished(const StringName &p_name) {
 | 
					void SceneImportSettingsDialog::_animation_finished(const StringName &p_name) {
 | 
				
			||||||
	Animation::LoopMode loop_mode = animation_loop_mode;
 | 
						Animation::LoopMode loop_mode = animation_loop_mode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1080,6 +1117,14 @@ void SceneImportSettingsDialog::_animation_finished(const StringName &p_name) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SceneImportSettingsDialog::_animation_update_skeleton_visibility() {
 | 
				
			||||||
 | 
						if (animation_toggle_skeleton_visibility->is_pressed()) {
 | 
				
			||||||
 | 
							bones_mesh_preview->show();
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							bones_mesh_preview->hide();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SceneImportSettingsDialog::_material_tree_selected() {
 | 
					void SceneImportSettingsDialog::_material_tree_selected() {
 | 
				
			||||||
	if (selecting) {
 | 
						if (selecting) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					@ -1282,6 +1327,8 @@ void SceneImportSettingsDialog::_notification(int p_what) {
 | 
				
			||||||
			light_1_switch->set_icon(theme_cache.light_1_icon);
 | 
								light_1_switch->set_icon(theme_cache.light_1_icon);
 | 
				
			||||||
			light_2_switch->set_icon(theme_cache.light_2_icon);
 | 
								light_2_switch->set_icon(theme_cache.light_2_icon);
 | 
				
			||||||
			light_rotate_switch->set_icon(theme_cache.rotate_icon);
 | 
								light_rotate_switch->set_icon(theme_cache.rotate_icon);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								animation_toggle_skeleton_visibility->set_icon(get_editor_theme_icon(SNAME("Skeleton3D")));
 | 
				
			||||||
		} break;
 | 
							} break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case NOTIFICATION_PROCESS: {
 | 
							case NOTIFICATION_PROCESS: {
 | 
				
			||||||
| 
						 | 
					@ -1661,6 +1708,7 @@ SceneImportSettingsDialog::SceneImportSettingsDialog() {
 | 
				
			||||||
	animation_hbox->add_child(animation_stop_button);
 | 
						animation_hbox->add_child(animation_stop_button);
 | 
				
			||||||
	animation_stop_button->set_flat(true);
 | 
						animation_stop_button->set_flat(true);
 | 
				
			||||||
	animation_stop_button->set_focus_mode(Control::FOCUS_NONE);
 | 
						animation_stop_button->set_focus_mode(Control::FOCUS_NONE);
 | 
				
			||||||
 | 
						animation_stop_button->set_tooltip_text(TTR("Selected Animation Stop"));
 | 
				
			||||||
	animation_stop_button->connect(SceneStringName(pressed), callable_mp(this, &SceneImportSettingsDialog::_stop_current_animation));
 | 
						animation_stop_button->connect(SceneStringName(pressed), callable_mp(this, &SceneImportSettingsDialog::_stop_current_animation));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	animation_slider = memnew(HSlider);
 | 
						animation_slider = memnew(HSlider);
 | 
				
			||||||
| 
						 | 
					@ -1673,6 +1721,15 @@ SceneImportSettingsDialog::SceneImportSettingsDialog() {
 | 
				
			||||||
	animation_slider->set_focus_mode(Control::FOCUS_NONE);
 | 
						animation_slider->set_focus_mode(Control::FOCUS_NONE);
 | 
				
			||||||
	animation_slider->connect(SceneStringName(value_changed), callable_mp(this, &SceneImportSettingsDialog::_animation_slider_value_changed));
 | 
						animation_slider->connect(SceneStringName(value_changed), callable_mp(this, &SceneImportSettingsDialog::_animation_slider_value_changed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						animation_toggle_skeleton_visibility = memnew(Button);
 | 
				
			||||||
 | 
						animation_hbox->add_child(animation_toggle_skeleton_visibility);
 | 
				
			||||||
 | 
						animation_toggle_skeleton_visibility->set_toggle_mode(true);
 | 
				
			||||||
 | 
						animation_toggle_skeleton_visibility->set_flat(true);
 | 
				
			||||||
 | 
						animation_toggle_skeleton_visibility->set_focus_mode(Control::FOCUS_NONE);
 | 
				
			||||||
 | 
						animation_toggle_skeleton_visibility->set_tooltip_text(TTR("Toggle Animation Skeleton Visibility"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						animation_toggle_skeleton_visibility->connect(SceneStringName(pressed), callable_mp(this, &SceneImportSettingsDialog::_animation_update_skeleton_visibility));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	base_viewport->set_use_own_world_3d(true);
 | 
						base_viewport->set_use_own_world_3d(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	HBoxContainer *viewport_hbox = memnew(HBoxContainer);
 | 
						HBoxContainer *viewport_hbox = memnew(HBoxContainer);
 | 
				
			||||||
| 
						 | 
					@ -1800,6 +1857,13 @@ SceneImportSettingsDialog::SceneImportSettingsDialog() {
 | 
				
			||||||
		collider_mat->set_albedo(Color(0.5, 0.5, 1.0));
 | 
							collider_mat->set_albedo(Color(0.5, 0.5, 1.0));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							bones_mesh_preview = memnew(MeshInstance3D);
 | 
				
			||||||
 | 
							bones_mesh_preview->set_cast_shadows_setting(GeometryInstance3D::SHADOW_CASTING_SETTING_OFF);
 | 
				
			||||||
 | 
							bones_mesh_preview->set_skeleton_path(NodePath());
 | 
				
			||||||
 | 
							base_viewport->add_child(bones_mesh_preview);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inspector = memnew(EditorInspector);
 | 
						inspector = memnew(EditorInspector);
 | 
				
			||||||
	inspector->set_custom_minimum_size(Size2(300 * EDSCALE, 0));
 | 
						inspector->set_custom_minimum_size(Size2(300 * EDSCALE, 0));
 | 
				
			||||||
	inspector->connect(SNAME("property_edited"), callable_mp(this, &SceneImportSettingsDialog::_inspector_property_edited));
 | 
						inspector->connect(SNAME("property_edited"), callable_mp(this, &SceneImportSettingsDialog::_inspector_property_edited));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -109,10 +109,12 @@ class SceneImportSettingsDialog : public ConfirmationDialog {
 | 
				
			||||||
	HSlider *animation_slider = nullptr;
 | 
						HSlider *animation_slider = nullptr;
 | 
				
			||||||
	Button *animation_play_button = nullptr;
 | 
						Button *animation_play_button = nullptr;
 | 
				
			||||||
	Button *animation_stop_button = nullptr;
 | 
						Button *animation_stop_button = nullptr;
 | 
				
			||||||
 | 
						Button *animation_toggle_skeleton_visibility = nullptr;
 | 
				
			||||||
	Animation::LoopMode animation_loop_mode = Animation::LOOP_NONE;
 | 
						Animation::LoopMode animation_loop_mode = Animation::LOOP_NONE;
 | 
				
			||||||
	bool animation_pingpong = false;
 | 
						bool animation_pingpong = false;
 | 
				
			||||||
	bool previous_import_as_skeleton = false;
 | 
						bool previous_import_as_skeleton = false;
 | 
				
			||||||
	bool previous_rest_as_reset = false;
 | 
						bool previous_rest_as_reset = false;
 | 
				
			||||||
 | 
						MeshInstance3D *bones_mesh_preview = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Ref<StandardMaterial3D> collider_mat;
 | 
						Ref<StandardMaterial3D> collider_mat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -187,9 +189,11 @@ class SceneImportSettingsDialog : public ConfirmationDialog {
 | 
				
			||||||
	void _reset_animation(const String &p_animation_name = "");
 | 
						void _reset_animation(const String &p_animation_name = "");
 | 
				
			||||||
	void _animation_slider_value_changed(double p_value);
 | 
						void _animation_slider_value_changed(double p_value);
 | 
				
			||||||
	void _animation_finished(const StringName &p_name);
 | 
						void _animation_finished(const StringName &p_name);
 | 
				
			||||||
 | 
						void _animation_update_skeleton_visibility();
 | 
				
			||||||
	void _material_tree_selected();
 | 
						void _material_tree_selected();
 | 
				
			||||||
	void _mesh_tree_selected();
 | 
						void _mesh_tree_selected();
 | 
				
			||||||
	void _scene_tree_selected();
 | 
						void _scene_tree_selected();
 | 
				
			||||||
 | 
						void _skeleton_tree_entered(Skeleton3D *p_skeleton);
 | 
				
			||||||
	void _cleanup();
 | 
						void _cleanup();
 | 
				
			||||||
	void _on_light_1_switch_pressed();
 | 
						void _on_light_1_switch_pressed();
 | 
				
			||||||
	void _on_light_2_switch_pressed();
 | 
						void _on_light_2_switch_pressed();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1348,16 +1348,18 @@ int Skeleton3DEditor::get_selected_bone() const {
 | 
				
			||||||
	return selected_bone;
 | 
						return selected_bone;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Skeleton3DGizmoPlugin::Skeleton3DGizmoPlugin() {
 | 
					Skeleton3DGizmoPlugin::SelectionMaterials Skeleton3DGizmoPlugin::selection_materials;
 | 
				
			||||||
	unselected_mat = Ref<StandardMaterial3D>(memnew(StandardMaterial3D));
 | 
					 | 
				
			||||||
	unselected_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
 | 
					 | 
				
			||||||
	unselected_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
 | 
					 | 
				
			||||||
	unselected_mat->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
 | 
					 | 
				
			||||||
	unselected_mat->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true);
 | 
					 | 
				
			||||||
	unselected_mat->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	selected_mat = Ref<ShaderMaterial>(memnew(ShaderMaterial));
 | 
					Skeleton3DGizmoPlugin::Skeleton3DGizmoPlugin() {
 | 
				
			||||||
	selected_sh = Ref<Shader>(memnew(Shader));
 | 
						selection_materials.unselected_mat.instantiate();
 | 
				
			||||||
 | 
						selection_materials.unselected_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
 | 
				
			||||||
 | 
						selection_materials.unselected_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
 | 
				
			||||||
 | 
						selection_materials.unselected_mat->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
 | 
				
			||||||
 | 
						selection_materials.unselected_mat->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true);
 | 
				
			||||||
 | 
						selection_materials.unselected_mat->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						selection_materials.selected_mat.instantiate();
 | 
				
			||||||
 | 
						Ref<Shader> selected_sh = Ref<Shader>(memnew(Shader));
 | 
				
			||||||
	selected_sh->set_code(R"(
 | 
						selected_sh->set_code(R"(
 | 
				
			||||||
// Skeleton 3D gizmo bones shader.
 | 
					// Skeleton 3D gizmo bones shader.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1376,7 +1378,7 @@ void fragment() {
 | 
				
			||||||
	ALPHA = COLOR.a;
 | 
						ALPHA = COLOR.a;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
)");
 | 
					)");
 | 
				
			||||||
	selected_mat->set_shader(selected_sh);
 | 
						selection_materials.selected_mat->set_shader(selected_sh);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Register properties in editor settings.
 | 
						// Register properties in editor settings.
 | 
				
			||||||
	EDITOR_DEF_RST("editors/3d_gizmos/gizmo_colors/skeleton", Color(1, 0.8, 0.4));
 | 
						EDITOR_DEF_RST("editors/3d_gizmos/gizmo_colors/skeleton", Color(1, 0.8, 0.4));
 | 
				
			||||||
| 
						 | 
					@ -1386,6 +1388,11 @@ void fragment() {
 | 
				
			||||||
	EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "editors/3d_gizmos/gizmo_settings/bone_shape", PROPERTY_HINT_ENUM, "Wire,Octahedron"));
 | 
						EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "editors/3d_gizmos/gizmo_settings/bone_shape", PROPERTY_HINT_ENUM, "Wire,Octahedron"));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Skeleton3DGizmoPlugin::~Skeleton3DGizmoPlugin() {
 | 
				
			||||||
 | 
						selection_materials.unselected_mat.unref();
 | 
				
			||||||
 | 
						selection_materials.selected_mat.unref();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool Skeleton3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
 | 
					bool Skeleton3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
 | 
				
			||||||
	return Object::cast_to<Skeleton3D>(p_spatial) != nullptr;
 | 
						return Object::cast_to<Skeleton3D>(p_spatial) != nullptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1526,6 +1533,11 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
 | 
				
			||||||
		selected = se->get_selected_bone();
 | 
							selected = se->get_selected_bone();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Ref<ArrayMesh> m = get_bones_mesh(skeleton, selected, p_gizmo->is_selected());
 | 
				
			||||||
 | 
						p_gizmo->add_mesh(m, Ref<Material>(), Transform3D(), skeleton->register_skin(skeleton->create_skin_from_rest_transforms()));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Ref<ArrayMesh> Skeleton3DGizmoPlugin::get_bones_mesh(Skeleton3D *p_skeleton, int p_selected, bool p_is_selected) {
 | 
				
			||||||
	Color bone_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/skeleton");
 | 
						Color bone_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/skeleton");
 | 
				
			||||||
	Color selected_bone_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/selected_bone");
 | 
						Color selected_bone_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/selected_bone");
 | 
				
			||||||
	real_t bone_axis_length = EDITOR_GET("editors/3d_gizmos/gizmo_settings/bone_axis_length");
 | 
						real_t bone_axis_length = EDITOR_GET("editors/3d_gizmos/gizmo_settings/bone_axis_length");
 | 
				
			||||||
| 
						 | 
					@ -1539,11 +1551,11 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
 | 
				
			||||||
	Ref<SurfaceTool> surface_tool(memnew(SurfaceTool));
 | 
						Ref<SurfaceTool> surface_tool(memnew(SurfaceTool));
 | 
				
			||||||
	surface_tool->begin(Mesh::PRIMITIVE_LINES);
 | 
						surface_tool->begin(Mesh::PRIMITIVE_LINES);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (p_gizmo->is_selected()) {
 | 
						if (p_is_selected) {
 | 
				
			||||||
		surface_tool->set_material(selected_mat);
 | 
							surface_tool->set_material(selection_materials.selected_mat);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		unselected_mat->set_albedo(bone_color);
 | 
							selection_materials.unselected_mat->set_albedo(bone_color);
 | 
				
			||||||
		surface_tool->set_material(unselected_mat);
 | 
							surface_tool->set_material(selection_materials.unselected_mat);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	LocalVector<int> bones;
 | 
						LocalVector<int> bones;
 | 
				
			||||||
| 
						 | 
					@ -1557,16 +1569,16 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
 | 
				
			||||||
	weights[0] = 1;
 | 
						weights[0] = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int current_bone_index = 0;
 | 
						int current_bone_index = 0;
 | 
				
			||||||
	Vector<int> bones_to_process = skeleton->get_parentless_bones();
 | 
						Vector<int> bones_to_process = p_skeleton->get_parentless_bones();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (bones_to_process.size() > current_bone_index) {
 | 
						while (bones_to_process.size() > current_bone_index) {
 | 
				
			||||||
		int current_bone_idx = bones_to_process[current_bone_index];
 | 
							int current_bone_idx = bones_to_process[current_bone_index];
 | 
				
			||||||
		current_bone_index++;
 | 
							current_bone_index++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Color current_bone_color = (current_bone_idx == selected) ? selected_bone_color : bone_color;
 | 
							Color current_bone_color = (current_bone_idx == p_selected) ? selected_bone_color : bone_color;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Vector<int> child_bones_vector;
 | 
							Vector<int> child_bones_vector;
 | 
				
			||||||
		child_bones_vector = skeleton->get_bone_children(current_bone_idx);
 | 
							child_bones_vector = p_skeleton->get_bone_children(current_bone_idx);
 | 
				
			||||||
		int child_bones_size = child_bones_vector.size();
 | 
							int child_bones_size = child_bones_vector.size();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (int i = 0; i < child_bones_size; i++) {
 | 
							for (int i = 0; i < child_bones_size; i++) {
 | 
				
			||||||
| 
						 | 
					@ -1577,8 +1589,8 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			int child_bone_idx = child_bones_vector[i];
 | 
								int child_bone_idx = child_bones_vector[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			Vector3 v0 = skeleton->get_bone_global_rest(current_bone_idx).origin;
 | 
								Vector3 v0 = p_skeleton->get_bone_global_rest(current_bone_idx).origin;
 | 
				
			||||||
			Vector3 v1 = skeleton->get_bone_global_rest(child_bone_idx).origin;
 | 
								Vector3 v1 = p_skeleton->get_bone_global_rest(child_bone_idx).origin;
 | 
				
			||||||
			Vector3 d = (v1 - v0).normalized();
 | 
								Vector3 d = (v1 - v0).normalized();
 | 
				
			||||||
			real_t dist = v0.distance_to(v1);
 | 
								real_t dist = v0.distance_to(v1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1586,7 +1598,7 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
 | 
				
			||||||
			int closest = -1;
 | 
								int closest = -1;
 | 
				
			||||||
			real_t closest_d = 0.0;
 | 
								real_t closest_d = 0.0;
 | 
				
			||||||
			for (int j = 0; j < 3; j++) {
 | 
								for (int j = 0; j < 3; j++) {
 | 
				
			||||||
				real_t dp = Math::abs(skeleton->get_bone_global_rest(current_bone_idx).basis[j].normalized().dot(d));
 | 
									real_t dp = Math::abs(p_skeleton->get_bone_global_rest(current_bone_idx).basis[j].normalized().dot(d));
 | 
				
			||||||
				if (j == 0 || dp > closest_d) {
 | 
									if (j == 0 || dp > closest_d) {
 | 
				
			||||||
					closest = j;
 | 
										closest = j;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
| 
						 | 
					@ -1613,7 +1625,7 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
 | 
				
			||||||
					for (int j = 0; j < 3; j++) {
 | 
										for (int j = 0; j < 3; j++) {
 | 
				
			||||||
						Vector3 axis;
 | 
											Vector3 axis;
 | 
				
			||||||
						if (first == Vector3()) {
 | 
											if (first == Vector3()) {
 | 
				
			||||||
							axis = d.cross(d.cross(skeleton->get_bone_global_rest(current_bone_idx).basis[j])).normalized();
 | 
												axis = d.cross(d.cross(p_skeleton->get_bone_global_rest(current_bone_idx).basis[j])).normalized();
 | 
				
			||||||
							first = axis;
 | 
												first = axis;
 | 
				
			||||||
						} else {
 | 
											} else {
 | 
				
			||||||
							axis = d.cross(first).normalized();
 | 
												axis = d.cross(first).normalized();
 | 
				
			||||||
| 
						 | 
					@ -1668,7 +1680,7 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
 | 
				
			||||||
				surface_tool->add_vertex(v0);
 | 
									surface_tool->add_vertex(v0);
 | 
				
			||||||
				surface_tool->set_bones(bones);
 | 
									surface_tool->set_bones(bones);
 | 
				
			||||||
				surface_tool->set_weights(weights);
 | 
									surface_tool->set_weights(weights);
 | 
				
			||||||
				surface_tool->add_vertex(v0 + (skeleton->get_bone_global_rest(current_bone_idx).basis.inverse())[j].normalized() * dist * bone_axis_length);
 | 
									surface_tool->add_vertex(v0 + (p_skeleton->get_bone_global_rest(current_bone_idx).basis.inverse())[j].normalized() * dist * bone_axis_length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (j == closest) {
 | 
									if (j == closest) {
 | 
				
			||||||
					continue;
 | 
										continue;
 | 
				
			||||||
| 
						 | 
					@ -1685,7 +1697,7 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
 | 
				
			||||||
					surface_tool->add_vertex(v1);
 | 
										surface_tool->add_vertex(v1);
 | 
				
			||||||
					surface_tool->set_bones(bones);
 | 
										surface_tool->set_bones(bones);
 | 
				
			||||||
					surface_tool->set_weights(weights);
 | 
										surface_tool->set_weights(weights);
 | 
				
			||||||
					surface_tool->add_vertex(v1 + (skeleton->get_bone_global_rest(child_bone_idx).basis.inverse())[j].normalized() * dist * bone_axis_length);
 | 
										surface_tool->add_vertex(v1 + (p_skeleton->get_bone_global_rest(child_bone_idx).basis.inverse())[j].normalized() * dist * bone_axis_length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if (j == closest) {
 | 
										if (j == closest) {
 | 
				
			||||||
						continue;
 | 
											continue;
 | 
				
			||||||
| 
						 | 
					@ -1698,6 +1710,5 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Ref<ArrayMesh> m = surface_tool->commit();
 | 
						return surface_tool->commit();
 | 
				
			||||||
	p_gizmo->add_mesh(m, Ref<Material>(), Transform3D(), skeleton->register_skin(skeleton->create_skin_from_rest_transforms()));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -260,11 +260,15 @@ public:
 | 
				
			||||||
class Skeleton3DGizmoPlugin : public EditorNode3DGizmoPlugin {
 | 
					class Skeleton3DGizmoPlugin : public EditorNode3DGizmoPlugin {
 | 
				
			||||||
	GDCLASS(Skeleton3DGizmoPlugin, EditorNode3DGizmoPlugin);
 | 
						GDCLASS(Skeleton3DGizmoPlugin, EditorNode3DGizmoPlugin);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct SelectionMaterials {
 | 
				
			||||||
		Ref<StandardMaterial3D> unselected_mat;
 | 
							Ref<StandardMaterial3D> unselected_mat;
 | 
				
			||||||
		Ref<ShaderMaterial> selected_mat;
 | 
							Ref<ShaderMaterial> selected_mat;
 | 
				
			||||||
	Ref<Shader> selected_sh;
 | 
						};
 | 
				
			||||||
 | 
						static SelectionMaterials selection_materials;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
						static Ref<ArrayMesh> get_bones_mesh(Skeleton3D *p_skeleton, int p_selected, bool p_is_selected);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool has_gizmo(Node3D *p_spatial) override;
 | 
						bool has_gizmo(Node3D *p_spatial) override;
 | 
				
			||||||
	String get_gizmo_name() const override;
 | 
						String get_gizmo_name() const override;
 | 
				
			||||||
	int get_priority() const override;
 | 
						int get_priority() const override;
 | 
				
			||||||
| 
						 | 
					@ -277,6 +281,7 @@ public:
 | 
				
			||||||
	void redraw(EditorNode3DGizmo *p_gizmo) override;
 | 
						void redraw(EditorNode3DGizmo *p_gizmo) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Skeleton3DGizmoPlugin();
 | 
						Skeleton3DGizmoPlugin();
 | 
				
			||||||
 | 
						~Skeleton3DGizmoPlugin();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // SKELETON_3D_EDITOR_PLUGIN_H
 | 
					#endif // SKELETON_3D_EDITOR_PLUGIN_H
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue