|
@@ -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));
|