From 66009706c92671898b49a8a88cc626926b7a2d2c Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sun, 23 Jul 2017 18:48:05 -0300 Subject: [PATCH] -Ability to set default import presets for type -More presets for scene importer -Option in scene importer to export root nodes as separate scenes -Fixed MeshInstance preview --- editor/editor_file_system.cpp | 15 +- editor/editor_node.cpp | 2 +- editor/import/resource_importer_scene.cpp | 107 +++++++++++--- editor/import/resource_importer_scene.h | 13 +- editor/import_dock.cpp | 61 +++++++- editor/import_dock.h | 6 + editor/plugins/mesh_editor_plugin.cpp | 165 ++++++++++------------ editor/plugins/mesh_editor_plugin.h | 23 ++- scene/resources/mesh.cpp | 2 +- scene/resources/mesh.h | 2 +- scene/resources/primitive_meshes.cpp | 148 ++++++++++--------- scene/resources/primitive_meshes.h | 27 ++-- 12 files changed, 348 insertions(+), 223 deletions(-) diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index f0f84416bfc..ed581163044 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -1239,7 +1239,7 @@ void EditorFileSystem::_reimport_file(const String &p_file) { String importer_name; if (FileAccess::exists(p_file + ".import")) { - + //use existing Ref cf; cf.instance(); Error err = cf->load(p_file + ".import"); @@ -1254,6 +1254,7 @@ void EditorFileSystem::_reimport_file(const String &p_file) { } Ref importer; + bool load_default = false; //find the importer if (importer_name != "") { importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(importer_name); @@ -1262,6 +1263,7 @@ void EditorFileSystem::_reimport_file(const String &p_file) { if (importer.is_null()) { //not found by name, find by extension importer = ResourceFormatImporter::get_singleton()->get_importer_by_extension(p_file.get_extension()); + load_default = true; if (importer.is_null()) { ERR_PRINT("BUG: File queued for import, but can't be imported!"); ERR_FAIL(); @@ -1278,6 +1280,17 @@ void EditorFileSystem::_reimport_file(const String &p_file) { } } + if (load_default && ProjectSettings::get_singleton()->get("importer_defaults/" + importer->get_importer_name())) { + //use defaults if exist + Dictionary d = ProjectSettings::get_singleton()->get("importer_defaults/" + importer->get_importer_name()); + List v; + d.get_key_list(&v); + + for (List::Element *E = v.front(); E; E = E->next()) { + params[E->get()] = d[E->get()]; + } + } + //finally, perform import!! String base_path = ResourceFormatImporter::get_singleton()->get_import_base_path(p_file); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index ce55438de45..b9a1ae29462 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -6079,7 +6079,7 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(TextureEditorPlugin(this))); add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor))); //add_editor_plugin( memnew( MaterialEditorPlugin(this) ) ); - //add_editor_plugin( memnew( MeshEditorPlugin(this) ) ); + add_editor_plugin(memnew(MeshEditorPlugin(this))); for (int i = 0; i < EditorPlugins::get_plugin_count(); i++) add_editor_plugin(EditorPlugins::create(i, this)); diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index dbf7a1bea5a..f96ce4871b1 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -104,14 +104,27 @@ bool ResourceImporterScene::get_option_visibility(const String &p_option, const } } + if (p_option == "materials/keep_files" && int(p_options["materials/storage"]) == 0) { + return false; + } + return true; } int ResourceImporterScene::get_preset_count() const { - return 0; + return 6; } String ResourceImporterScene::get_preset_name(int p_idx) const { + switch (p_idx) { + case PRESET_SINGLE_SCENE: return TTR("Import as Single Scene"); + case PRESET_SEPARATE_MATERIALS: return TTR("Import as Separate Materials"); + case PRESET_SEPARATE_MESHES: return TTR("Import as Separate Objects"); + case PRESET_SEPARATE_MESHES_AND_MATERIALS: return TTR("Import as Separate Objects+Materials"); + case PRESET_MULTIPLE_SCENES: return TTR("Import as Multiple Scenes"); + case PRESET_MULTIPLE_SCENES_AND_MATERIALS: return TTR("Import as Multiple Scenes+Materials"); + } + return ""; } @@ -969,7 +982,7 @@ static String _make_extname(const String &p_str) { return ext_name; } -void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_make_meshes, Map, Ref > &p_materials, Map, Ref > &p_meshes) { +void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map, Ref > &p_materials, Map, Ref > &p_meshes) { List pi; @@ -984,8 +997,8 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String if (!p_materials.has(mat)) { - String ext_name = p_base_path + "." + _make_extname(mat->get_name()) + ".material"; - if (FileAccess::exists(ext_name)) { + String ext_name = p_base_path.plus_file(_make_extname(mat->get_name()) + ".material"); + if (p_keep_materials && FileAccess::exists(ext_name)) { //if exists, use it Ref existing = ResourceLoader::load(ext_name); p_materials[mat] = existing; @@ -1012,17 +1025,12 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String if (!p_meshes.has(mesh)) { - String ext_name = p_base_path + "." + _make_extname(mesh->get_name()) + ".mesh"; - if (FileAccess::exists(ext_name)) { - //if exists, use it - Ref existing = ResourceLoader::load(ext_name); - p_meshes[mesh] = existing; - } else { + //meshes are always overwritten, keeping them is not practical + String ext_name = p_base_path.plus_file(_make_extname(mesh->get_name()) + ".mesh"); - ResourceSaver::save(ext_name, mesh, ResourceSaver::FLAG_CHANGE_PATH); - p_meshes[mesh] = mesh; - mesh_just_added = true; - } + ResourceSaver::save(ext_name, mesh, ResourceSaver::FLAG_CHANGE_PATH); + p_meshes[mesh] = mesh; + mesh_just_added = true; } } @@ -1067,7 +1075,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String for (int i = 0; i < p_node->get_child_count(); i++) { - _make_external_resources(p_node->get_child(i), p_base_path, p_make_materials, p_make_meshes, p_materials, p_meshes); + _make_external_resources(p_node->get_child(i), p_base_path, p_make_materials, p_keep_materials, p_make_meshes, p_materials, p_meshes); } } @@ -1087,12 +1095,19 @@ void ResourceImporterScene::get_import_options(List *r_options, in script_ext_hint += "*." + E->get(); } + bool materials_out = p_preset == PRESET_SEPARATE_MATERIALS || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS || p_preset == PRESET_MULTIPLE_SCENES_AND_MATERIALS; + bool meshes_out = p_preset == PRESET_SEPARATE_MESHES || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS; + bool scenes_out = p_preset == PRESET_MULTIPLE_SCENES || p_preset == PRESET_MULTIPLE_SCENES_AND_MATERIALS; + r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/custom_script", PROPERTY_HINT_FILE, script_ext_hint), "")); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/location", PROPERTY_HINT_ENUM, "Node,Mesh"), 0)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/storage", PROPERTY_HINT_ENUM, "Bult-In,Files"), 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "nodes/storage", PROPERTY_HINT_ENUM, "Single Scene,Instanced Sub-Scenes"), scenes_out ? 1 : 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/location", PROPERTY_HINT_ENUM, "Node,Mesh"), meshes_out ? 1 : 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/storage", PROPERTY_HINT_ENUM, "Bult-In,Files", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), materials_out ? 1 : 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "materials/keep_files"), materials_out ? true : false)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "geometry/compress"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "geometry/ensure_tangents"), true)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "geometry/storage", PROPERTY_HINT_ENUM, "Built-In,Files"), 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "geometry/storage", PROPERTY_HINT_ENUM, "Built-In,Files"), meshes_out ? true : false)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "external_files/store_in_subdir"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 15)); r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "animation/filter_script", PROPERTY_HINT_MULTILINE_TEXT), "")); @@ -1110,6 +1125,18 @@ void ResourceImporterScene::get_import_options(List *r_options, in } } +void ResourceImporterScene::_replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner) { + + if (p_node != p_new_owner && p_node->get_owner() == p_scene) { + p_node->set_owner(p_new_owner); + } + + for (int i = 0; i < p_node->get_child_count(); i++) { + Node *n = p_node->get_child(i); + _replace_owner(n, p_scene, p_new_owner); + } +} + Error ResourceImporterScene::import(const String &p_source_file, const String &p_save_path, const Map &p_options, List *r_platform_variants, List *r_gen_files) { String src_path = p_source_file; @@ -1224,11 +1251,30 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p bool external_materials = p_options["materials/storage"]; bool external_meshes = p_options["geometry/storage"]; + bool external_scenes = int(p_options["nodes/storage"]) == 1; + + String base_path = p_source_file.get_base_dir(); + + if (external_materials || external_meshes || external_scenes) { + + if (bool(p_options["external_files/store_in_subdir"])) { + String subdir_name = p_source_file.get_file().get_basename(); + DirAccess *da = DirAccess::open(base_path); + print_line("at path " + da->get_current_dir() + " making " + subdir_name); + Error err = da->make_dir(subdir_name); + memdelete(da); + ERR_FAIL_COND_V(err != OK && err != ERR_ALREADY_EXISTS, err); + base_path = base_path.plus_file(subdir_name); + } + } if (external_materials || external_meshes) { Map, Ref > mat_map; Map, Ref > mesh_map; - _make_external_resources(scene, p_source_file.get_basename(), external_materials, external_meshes, mat_map, mesh_map); + + bool keep_materials = bool(p_options["materials/keep_files"]); + + _make_external_resources(scene, base_path, external_materials, keep_materials, external_meshes, mat_map, mesh_map); } progress.step(TTR("Running Custom Script.."), 2); @@ -1263,10 +1309,33 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p progress.step(TTR("Saving.."), 104); + if (external_scenes) { + //save sub-scenes as instances! + for (int i = 0; i < scene->get_child_count(); i++) { + Node *child = scene->get_child(i); + if (child->get_owner() != scene) + continue; //not a real child probably created by scene type (ig, a scrollbar) + _replace_owner(child, scene, child); + + String cn = String(child->get_name()).strip_edges().replace(".", "_").replace(":", "_"); + if (cn == String()) { + cn = "ChildNode" + itos(i); + } + String path = base_path.plus_file(cn + ".scn"); + child->set_filename(path); + + Ref packer = memnew(PackedScene); + packer->pack(child); + err = ResourceSaver::save(path, packer); //do not take over, let the changed files reload themselves + ERR_FAIL_COND_V(err != OK, err); + } + } + Ref packer = memnew(PackedScene); packer->pack(scene); print_line("SAVING TO: " + p_save_path + ".scn"); err = ResourceSaver::save(p_save_path + ".scn", packer); //do not take over, let the changed files reload themselves + ERR_FAIL_COND_V(err != OK, err); memdelete(scene); diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index ede3028b297..f404582d7e3 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -82,6 +82,17 @@ class ResourceImporterScene : public ResourceImporter { static ResourceImporterScene *singleton; + enum Presets { + PRESET_SINGLE_SCENE, + PRESET_SEPARATE_MATERIALS, + PRESET_SEPARATE_MESHES, + PRESET_SEPARATE_MESHES_AND_MATERIALS, + PRESET_MULTIPLE_SCENES, + PRESET_MULTIPLE_SCENES_AND_MATERIALS, + }; + + void _replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner); + public: static ResourceImporterScene *get_singleton() { return singleton; } @@ -101,7 +112,7 @@ public: virtual void get_import_options(List *r_options, int p_preset = 0) const; virtual bool get_option_visibility(const String &p_option, const Map &p_options) const; - void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_make_meshes, Map, Ref > &p_materials, Map, Ref > &p_meshes); + void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map, Ref > &p_materials, Map, Ref > &p_meshes); Node *_fix_node(Node *p_node, Node *p_root, Map, Ref > &collision_map); diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp index dff36ae7420..a4f744aa844 100644 --- a/editor/import_dock.cpp +++ b/editor/import_dock.cpp @@ -134,6 +134,14 @@ void ImportDock::set_edit_path(const String &p_path) { } } + preset->get_popup()->add_separator(); + preset->get_popup()->add_item(vformat(TTR("Set as Default for '%s'"), params->importer->get_visible_name()), ITEM_SET_AS_DEFAULT); + if (ProjectSettings::get_singleton()->has("importer_defaults/" + params->importer->get_importer_name())) { + preset->get_popup()->add_item(TTR("Load Default"), ITEM_LOAD_DEFAULT); + preset->get_popup()->add_separator(); + preset->get_popup()->add_item(vformat(TTR("Clear Default for '%s'"), params->importer->get_visible_name()), ITEM_CLEAR_DEFAULT); + } + params->paths.clear(); params->paths.push_back(p_path); import->set_disabled(false); @@ -256,17 +264,56 @@ void ImportDock::set_edit_multiple_paths(const Vector &p_paths) { void ImportDock::_preset_selected(int p_idx) { - print_line("preset selected? " + p_idx); - List options; + switch (p_idx) { + case ITEM_SET_AS_DEFAULT: { + List options; - params->importer->get_import_options(&options, p_idx); + params->importer->get_import_options(&options, p_idx); - for (List::Element *E = options.front(); E; E = E->next()) { + Dictionary d; + for (List::Element *E = options.front(); E; E = E->next()) { - params->values[E->get().option.name] = E->get().default_value; + d[E->get().option.name] = E->get().default_value; + } + + ProjectSettings::get_singleton()->set("importer_defaults/" + params->importer->get_importer_name(), d); + ProjectSettings::get_singleton()->save(); + + } break; + case ITEM_LOAD_DEFAULT: { + + ERR_FAIL_COND(!ProjectSettings::get_singleton()->has("importer_defaults/" + params->importer->get_importer_name())); + + Dictionary d = ProjectSettings::get_singleton()->get("importer_defaults/" + params->importer->get_importer_name()); + List v; + d.get_key_list(&v); + + for (List::Element *E = v.front(); E; E = E->next()) { + params->values[E->get()] = d[E->get()]; + } + params->update(); + + } break; + case ITEM_CLEAR_DEFAULT: { + + ProjectSettings::get_singleton()->set("importer_defaults/" + params->importer->get_importer_name(), Variant()); + ProjectSettings::get_singleton()->save(); + + } break; + default: { + + List options; + + params->importer->get_import_options(&options, p_idx); + + for (List::Element *E = options.front(); E; E = E->next()) { + + params->values[E->get().option.name] = E->get().default_value; + } + + params->update(); + } break; } - - params->update(); } void ImportDock::clear() { diff --git a/editor/import_dock.h b/editor/import_dock.h index 171aabe407d..4844fc07ea2 100644 --- a/editor/import_dock.h +++ b/editor/import_dock.h @@ -57,6 +57,12 @@ class ImportDock : public VBoxContainer { void _reimport(); + enum { + ITEM_SET_AS_DEFAULT = 100, + ITEM_LOAD_DEFAULT, + ITEM_CLEAR_DEFAULT, + }; + protected: static void _bind_methods(); diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp index f377d3a7cc7..23b19e61b91 100644 --- a/editor/plugins/mesh_editor_plugin.cpp +++ b/editor/plugins/mesh_editor_plugin.cpp @@ -29,18 +29,17 @@ /*************************************************************************/ #include "mesh_editor_plugin.h" -#if 0 -void MeshEditor::_gui_input(InputEvent p_event) { +void MeshEditor::_gui_input(Ref p_event) { + Ref mm = p_event; + if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) { - if (p_event.type==InputEvent::MOUSE_MOTION && p_event->get_button_mask()&BUTTON_MASK_LEFT) { - - rot_x-=p_event->get_relative().y*0.01; - rot_y-=p_event->get_relative().x*0.01; - if (rot_x<-Math_PI/2) - rot_x=-Math_PI/2; - else if (rot_x>Math_PI/2) { - rot_x=Math_PI/2; + rot_x -= mm->get_relative().y * 0.01; + rot_y -= mm->get_relative().x * 0.01; + if (rot_x < -Math_PI / 2) + rot_x = -Math_PI / 2; + else if (rot_x > Math_PI / 2) { + rot_x = Math_PI / 2; } _update_rotation(); } @@ -48,35 +47,30 @@ void MeshEditor::_gui_input(InputEvent p_event) { void MeshEditor::_notification(int p_what) { - if (p_what==NOTIFICATION_FIXED_PROCESS) { - + if (p_what == NOTIFICATION_FIXED_PROCESS) { } - - if (p_what==NOTIFICATION_READY) { + if (p_what == NOTIFICATION_READY) { //get_scene()->connect("node_removed",this,"_node_removed"); if (first_enter) { - //it's in propertyeditor so.. could be moved around + //it's in propertyeditor so. could be moved around - light_1_switch->set_normal_texture(get_icon("MaterialPreviewLight1","EditorIcons")); - light_1_switch->set_pressed_texture(get_icon("MaterialPreviewLight1Off","EditorIcons")); - light_2_switch->set_normal_texture(get_icon("MaterialPreviewLight2","EditorIcons")); - light_2_switch->set_pressed_texture(get_icon("MaterialPreviewLight2Off","EditorIcons")); - first_enter=false; + light_1_switch->set_normal_texture(get_icon("MaterialPreviewLight1", "EditorIcons")); + light_1_switch->set_pressed_texture(get_icon("MaterialPreviewLight1Off", "EditorIcons")); + light_2_switch->set_normal_texture(get_icon("MaterialPreviewLight2", "EditorIcons")); + light_2_switch->set_pressed_texture(get_icon("MaterialPreviewLight2Off", "EditorIcons")); + first_enter = false; } - } - if (p_what==NOTIFICATION_DRAW) { + if (p_what == NOTIFICATION_DRAW) { - - Ref checkerboard = get_icon("Checkerboard","EditorIcons"); + Ref checkerboard = get_icon("Checkerboard", "EditorIcons"); Size2 size = get_size(); - draw_texture_rect(checkerboard,Rect2(Point2(),size),true); - + //draw_texture_rect(checkerboard, Rect2(Point2(), size), true); } } @@ -85,125 +79,115 @@ void MeshEditor::_update_rotation() { Transform t; t.basis.rotate(Vector3(0, 1, 0), -rot_y); t.basis.rotate(Vector3(1, 0, 0), -rot_x); - mesh_instance->set_transform(t); - + rotation->set_transform(t); } void MeshEditor::edit(Ref p_mesh) { - mesh=p_mesh; + mesh = p_mesh; mesh_instance->set_mesh(mesh); if (mesh.is_null()) { hide(); } else { - rot_x=0; - rot_y=0; + rot_x = 0; + rot_y = 0; _update_rotation(); - AABB aabb= mesh->get_aabb(); - Vector3 ofs = aabb.pos + aabb.size*0.5; - aabb.pos-=ofs; - float m = MAX(aabb.size.x,aabb.size.y)*0.5; - if (m!=0) { - m=1.0/m; - m*=0.5; + Rect3 aabb = mesh->get_aabb(); + print_line("aabb: " + aabb); + Vector3 ofs = aabb.position + aabb.size * 0.5; + float m = aabb.get_longest_axis_size(); + if (m != 0) { + m = 1.0 / m; + m *= 0.5; //print_line("scale: "+rtos(m)); Transform xform; - xform.basis.scale(Vector3(m,m,m)); - xform.origin=-xform.basis.xform(ofs); //-ofs*m; - xform.origin.z-=aabb.size.z*2; + xform.basis.scale(Vector3(m, m, m)); + xform.origin = -xform.basis.xform(ofs); //-ofs*m; + //xform.origin.z -= aabb.get_longest_axis_size() * 2; mesh_instance->set_transform(xform); } - } - } +void MeshEditor::_button_pressed(Node *p_button) { -void MeshEditor::_button_pressed(Node* p_button) { - - if (p_button==light_1_switch) { - light1->set_enabled(!light_1_switch->is_pressed()); + if (p_button == light_1_switch) { + light1->set_visible(!light_1_switch->is_pressed()); } - if (p_button==light_2_switch) { - light2->set_enabled(!light_2_switch->is_pressed()); + if (p_button == light_2_switch) { + light2->set_visible(!light_2_switch->is_pressed()); } - - } void MeshEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("_gui_input"),&MeshEditor::_gui_input); - ClassDB::bind_method(D_METHOD("_button_pressed"),&MeshEditor::_button_pressed); - + ClassDB::bind_method(D_METHOD("_gui_input"), &MeshEditor::_gui_input); + ClassDB::bind_method(D_METHOD("_button_pressed"), &MeshEditor::_button_pressed); } MeshEditor::MeshEditor() { - viewport = memnew( Viewport ); + viewport = memnew(Viewport); Ref world; world.instance(); viewport->set_world(world); //use own world add_child(viewport); viewport->set_disable_input(true); + set_stretch(true); - camera = memnew( Camera ); - camera->set_transform(Transform(Matrix3(),Vector3(0,0,3))); - camera->set_perspective(45,0.1,10); + camera = memnew(Camera); + camera->set_transform(Transform(Basis(), Vector3(0, 0, 1.1))); + camera->set_perspective(45, 0.1, 10); viewport->add_child(camera); - light1 = memnew( DirectionalLight ); - light1->set_transform(Transform().looking_at(Vector3(-1,-1,-1),Vector3(0,1,0))); + light1 = memnew(DirectionalLight); + light1->set_transform(Transform().looking_at(Vector3(-1, -1, -1), Vector3(0, 1, 0))); viewport->add_child(light1); - light2 = memnew( DirectionalLight ); - light2->set_transform(Transform().looking_at(Vector3(0,1,0),Vector3(0,0,1))); - light2->set_color(Light::COLOR_DIFFUSE,Color(0.7,0.7,0.7)); - light2->set_color(Light::COLOR_SPECULAR,Color(0.7,0.7,0.7)); + light2 = memnew(DirectionalLight); + light2->set_transform(Transform().looking_at(Vector3(0, 1, 0), Vector3(0, 0, 1))); + light2->set_color(Color(0.7, 0.7, 0.7)); viewport->add_child(light2); - mesh_instance = memnew( MeshInstance ); - viewport->add_child(mesh_instance); + rotation = memnew(Spatial); + viewport->add_child(rotation); + mesh_instance = memnew(MeshInstance); + rotation->add_child(mesh_instance); + set_custom_minimum_size(Size2(1, 150) * EDSCALE); - - set_custom_minimum_size(Size2(1,150)*EDSCALE); - - HBoxContainer *hb = memnew( HBoxContainer ); + HBoxContainer *hb = memnew(HBoxContainer); add_child(hb); hb->set_area_as_parent_rect(2); hb->add_spacer(); - VBoxContainer *vb_light = memnew( VBoxContainer ); + VBoxContainer *vb_light = memnew(VBoxContainer); hb->add_child(vb_light); - light_1_switch = memnew( TextureButton ); + light_1_switch = memnew(TextureButton); light_1_switch->set_toggle_mode(true); vb_light->add_child(light_1_switch); - light_1_switch->connect("pressed",this,"_button_pressed",varray(light_1_switch)); + light_1_switch->connect("pressed", this, "_button_pressed", varray(light_1_switch)); - light_2_switch = memnew( TextureButton ); + light_2_switch = memnew(TextureButton); light_2_switch->set_toggle_mode(true); vb_light->add_child(light_2_switch); - light_2_switch->connect("pressed",this,"_button_pressed",varray(light_2_switch)); - - first_enter=true; - - rot_x=0; - rot_y=0; + light_2_switch->connect("pressed", this, "_button_pressed", varray(light_2_switch)); + first_enter = true; + rot_x = 0; + rot_y = 0; } - void MeshEditorPlugin::edit(Object *p_object) { - Mesh * s = p_object->cast_to(); + Mesh *s = p_object->cast_to(); if (!s) return; @@ -212,7 +196,7 @@ void MeshEditorPlugin::edit(Object *p_object) { bool MeshEditorPlugin::handles(Object *p_object) const { - return p_object->is_type("Mesh"); + return p_object->is_class("Mesh"); } void MeshEditorPlugin::make_visible(bool p_visible) { @@ -225,22 +209,15 @@ void MeshEditorPlugin::make_visible(bool p_visible) { mesh_editor->hide(); //mesh_editor->set_process(false); } - } MeshEditorPlugin::MeshEditorPlugin(EditorNode *p_node) { - editor=p_node; - mesh_editor = memnew( MeshEditor ); - add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM,mesh_editor); + editor = p_node; + mesh_editor = memnew(MeshEditor); + add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM, mesh_editor); mesh_editor->hide(); - - - } - -MeshEditorPlugin::~MeshEditorPlugin() -{ +MeshEditorPlugin::~MeshEditorPlugin() { } -#endif diff --git a/editor/plugins/mesh_editor_plugin.h b/editor/plugins/mesh_editor_plugin.h index 1d89448ed85..72d93c41266 100644 --- a/editor/plugins/mesh_editor_plugin.h +++ b/editor/plugins/mesh_editor_plugin.h @@ -30,8 +30,6 @@ #ifndef MESH_EDITOR_PLUGIN_H #define MESH_EDITOR_PLUGIN_H -#if 0 - #include "editor/editor_node.h" #include "editor/editor_plugin.h" #include "scene/3d/camera.h" @@ -39,51 +37,48 @@ #include "scene/3d/mesh_instance.h" #include "scene/resources/material.h" -class MeshEditor : public Control { - - GDCLASS(MeshEditor, Control); - +class MeshEditor : public ViewportContainer { + GDCLASS(MeshEditor, ViewportContainer); float rot_x; float rot_y; Viewport *viewport; MeshInstance *mesh_instance; + Spatial *rotation; DirectionalLight *light1; DirectionalLight *light2; Camera *camera; Ref mesh; - TextureButton *light_1_switch; TextureButton *light_2_switch; - void _button_pressed(Node* p_button); + void _button_pressed(Node *p_button); bool first_enter; void _update_rotation(); + protected: void _notification(int p_what); - void _gui_input(InputEvent p_event); + void _gui_input(Ref p_event); static void _bind_methods(); -public: +public: void edit(Ref p_mesh); MeshEditor(); }; - class MeshEditorPlugin : public EditorPlugin { - GDCLASS( MeshEditorPlugin, EditorPlugin ); + GDCLASS(MeshEditorPlugin, EditorPlugin); MeshEditor *mesh_editor; EditorNode *editor; public: - virtual String get_name() const { return "Mesh"; } bool has_main_screen() const { return false; } virtual void edit(Object *p_node); @@ -92,8 +87,6 @@ public: MeshEditorPlugin(EditorNode *p_node); ~MeshEditorPlugin(); - }; -#endif // MESH_EDITOR_PLUGIN_H #endif diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 414d0a62406..310ab5e371c 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -32,7 +32,7 @@ #include "scene/resources/convex_polygon_shape.h" #include "surface_tool.h" -void Mesh::_clear_triangle_mesh() { +void Mesh::_clear_triangle_mesh() const { triangle_mesh.unref(); ; diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 4adb871e09c..e40ef992375 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -44,7 +44,7 @@ class Mesh : public Resource { mutable Ref triangle_mesh; //cached protected: - void _clear_triangle_mesh(); + void _clear_triangle_mesh() const; static void _bind_methods(); diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index 81cfd0e5f08..327de2f6f38 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -34,42 +34,44 @@ /** PrimitiveMesh */ -void PrimitiveMesh::_update() { - if (!cache_is_dirty) - return; +void PrimitiveMesh::_update() const { Array arr; arr.resize(VS::ARRAY_MAX); _create_mesh_array(arr); + PoolVector points = arr[VS::ARRAY_VERTEX]; + + aabb = Rect3(); + + int pc = points.size(); + ERR_FAIL_COND(pc == 0); + { + + PoolVector::Read r = points.read(); + for (int i = 0; i < pc; i++) { + if (i == 0) + aabb.position = r[i]; + else + aabb.expand_to(r[i]); + } + } + // in with the new VisualServer::get_singleton()->mesh_clear(mesh); VisualServer::get_singleton()->mesh_add_surface_from_arrays(mesh, (VisualServer::PrimitiveType)primitive_type, arr); VisualServer::get_singleton()->mesh_surface_set_material(mesh, 0, material.is_null() ? RID() : material->get_rid()); - cache_is_dirty = false; + pending_request = false; _clear_triangle_mesh(); - emit_changed(); } -void PrimitiveMesh::_queue_update(bool p_first_mesh) { +void PrimitiveMesh::_request_update() { - if (first_mesh && p_first_mesh) { - first_mesh = false; - cache_is_dirty = true; - _update(); + if (pending_request) return; - } - - if (!cache_is_dirty) { - cache_is_dirty = true; - call_deferred("_update"); - } -} - -void PrimitiveMesh::set_aabb(Rect3 p_aabb) { - aabb = p_aabb; + _update(); } int PrimitiveMesh::get_surface_count() const { @@ -78,21 +80,37 @@ int PrimitiveMesh::get_surface_count() const { int PrimitiveMesh::surface_get_array_len(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, 1, -1); + if (pending_request) { + _update(); + } + return VisualServer::get_singleton()->mesh_surface_get_array_len(mesh, 0); } int PrimitiveMesh::surface_get_array_index_len(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, 1, -1); + if (pending_request) { + _update(); + } + return VisualServer::get_singleton()->mesh_surface_get_array_index_len(mesh, 0); } Array PrimitiveMesh::surface_get_arrays(int p_surface) const { ERR_FAIL_INDEX_V(p_surface, 1, Array()); + if (pending_request) { + _update(); + } + return VisualServer::get_singleton()->mesh_surface_get_arrays(mesh, 0); } uint32_t PrimitiveMesh::surface_get_format(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, 1, 0); + if (pending_request) { + _update(); + } + return VisualServer::get_singleton()->mesh_surface_get_format(mesh, 0); } @@ -113,10 +131,17 @@ StringName PrimitiveMesh::get_blend_shape_name(int p_index) const { } Rect3 PrimitiveMesh::get_aabb() const { + if (pending_request) { + _update(); + } + return aabb; } RID PrimitiveMesh::get_rid() const { + if (pending_request) { + _update(); + } return mesh; } @@ -131,10 +156,9 @@ void PrimitiveMesh::_bind_methods() { void PrimitiveMesh::set_material(const Ref &p_material) { material = p_material; - if (!cache_is_dirty) { + if (!pending_request) { // just apply it, else it'll happen when _update is called. VisualServer::get_singleton()->mesh_surface_set_material(mesh, 0, material.is_null() ? RID() : material->get_rid()); - _change_notify(); emit_changed(); }; @@ -152,9 +176,7 @@ PrimitiveMesh::PrimitiveMesh() { primitive_type = Mesh::PRIMITIVE_TRIANGLES; // make sure we do an update after we've finished constructing our object - cache_is_dirty = false; - first_mesh = true; - _queue_update(); + pending_request = true; } PrimitiveMesh::~PrimitiveMesh() { @@ -165,7 +187,7 @@ PrimitiveMesh::~PrimitiveMesh() { CapsuleMesh */ -void CapsuleMesh::_create_mesh_array(Array &p_arr) { +void CapsuleMesh::_create_mesh_array(Array &p_arr) const { int i, j, prevrow, thisrow, point; float x, y, z, u, v, w; float onethird = 1.0 / 3.0; @@ -173,8 +195,6 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) { // note, this has been aligned with our collision shape but I've left the descriptions as top/middle/bottom - set_aabb(Rect3(Vector3(-radius, -radius, (mid_height * -0.5) - radius), Vector3(radius * 2.0, radius * 2.0, mid_height + (2.0 * radius)))); - PoolVector points; PoolVector normals; PoolVector tangents; @@ -334,7 +354,7 @@ void CapsuleMesh::_bind_methods() { void CapsuleMesh::set_radius(const float p_radius) { radius = p_radius; - _queue_update(); + _request_update(); } float CapsuleMesh::get_radius() const { @@ -343,7 +363,7 @@ float CapsuleMesh::get_radius() const { void CapsuleMesh::set_mid_height(const float p_mid_height) { mid_height = p_mid_height; - _queue_update(); + _request_update(); } float CapsuleMesh::get_mid_height() const { @@ -352,7 +372,7 @@ float CapsuleMesh::get_mid_height() const { void CapsuleMesh::set_radial_segments(const int p_segments) { radial_segments = p_segments > 4 ? p_segments : 4; - _queue_update(); + _request_update(); } int CapsuleMesh::get_radial_segments() const { @@ -361,7 +381,7 @@ int CapsuleMesh::get_radial_segments() const { void CapsuleMesh::set_rings(const int p_rings) { rings = p_rings > 1 ? p_rings : 1; - _queue_update(true); //last property set, force update mesh + _request_update(); } int CapsuleMesh::get_rings() const { @@ -380,7 +400,7 @@ CapsuleMesh::CapsuleMesh() { CubeMesh */ -void CubeMesh::_create_mesh_array(Array &p_arr) { +void CubeMesh::_create_mesh_array(Array &p_arr) const { int i, j, prevrow, thisrow, point; float x, y, z; float onethird = 1.0 / 3.0; @@ -389,7 +409,6 @@ void CubeMesh::_create_mesh_array(Array &p_arr) { Vector3 start_pos = size * -0.5; // set our bounding box - set_aabb(Rect3(start_pos, size)); PoolVector points; PoolVector normals; @@ -592,7 +611,7 @@ void CubeMesh::_bind_methods() { void CubeMesh::set_size(const Vector3 &p_size) { size = p_size; - _queue_update(); + _request_update(); } Vector3 CubeMesh::get_size() const { @@ -601,7 +620,7 @@ Vector3 CubeMesh::get_size() const { void CubeMesh::set_subdivide_width(const int p_subdivide) { subdivide_w = p_subdivide > 0 ? p_subdivide : 0; - _queue_update(); + _request_update(); } int CubeMesh::get_subdivide_width() const { @@ -610,7 +629,7 @@ int CubeMesh::get_subdivide_width() const { void CubeMesh::set_subdivide_height(const int p_subdivide) { subdivide_h = p_subdivide > 0 ? p_subdivide : 0; - _queue_update(); + _request_update(); } int CubeMesh::get_subdivide_height() const { @@ -619,7 +638,7 @@ int CubeMesh::get_subdivide_height() const { void CubeMesh::set_subdivide_depth(const int p_subdivide) { subdivide_d = p_subdivide > 0 ? p_subdivide : 0; - _queue_update(true); //last property set, force update mesh + _request_update(); } int CubeMesh::get_subdivide_depth() const { @@ -638,14 +657,12 @@ CubeMesh::CubeMesh() { CylinderMesh */ -void CylinderMesh::_create_mesh_array(Array &p_arr) { +void CylinderMesh::_create_mesh_array(Array &p_arr) const { int i, j, prevrow, thisrow, point; float x, y, z, u, v, radius; radius = bottom_radius > top_radius ? bottom_radius : top_radius; - set_aabb(Rect3(Vector3(-radius, height * -0.5, -radius), Vector3(radius * 2.0, height, radius * 2.0))); - PoolVector points; PoolVector normals; PoolVector tangents; @@ -800,7 +817,7 @@ void CylinderMesh::_bind_methods() { void CylinderMesh::set_top_radius(const float p_radius) { top_radius = p_radius; - _queue_update(); + _request_update(); } float CylinderMesh::get_top_radius() const { @@ -809,7 +826,7 @@ float CylinderMesh::get_top_radius() const { void CylinderMesh::set_bottom_radius(const float p_radius) { bottom_radius = p_radius; - _queue_update(); + _request_update(); } float CylinderMesh::get_bottom_radius() const { @@ -818,7 +835,7 @@ float CylinderMesh::get_bottom_radius() const { void CylinderMesh::set_height(const float p_height) { height = p_height; - _queue_update(); + _request_update(); } float CylinderMesh::get_height() const { @@ -827,7 +844,7 @@ float CylinderMesh::get_height() const { void CylinderMesh::set_radial_segments(const int p_segments) { radial_segments = p_segments > 4 ? p_segments : 4; - _queue_update(); + _request_update(); } int CylinderMesh::get_radial_segments() const { @@ -836,7 +853,7 @@ int CylinderMesh::get_radial_segments() const { void CylinderMesh::set_rings(const int p_rings) { rings = p_rings > 0 ? p_rings : 0; - _queue_update(true); //last property set, force update mesh + _request_update(); } int CylinderMesh::get_rings() const { @@ -856,14 +873,12 @@ CylinderMesh::CylinderMesh() { PlaneMesh */ -void PlaneMesh::_create_mesh_array(Array &p_arr) { +void PlaneMesh::_create_mesh_array(Array &p_arr) const { int i, j, prevrow, thisrow, point; float x, z; Size2 start_pos = size * -0.5; - set_aabb(Rect3(Vector3(start_pos.x, 0.0, start_pos.y), Vector3(size.x, 0.0, size.y))); - PoolVector points; PoolVector normals; PoolVector tangents; @@ -935,7 +950,7 @@ void PlaneMesh::_bind_methods() { void PlaneMesh::set_size(const Size2 &p_size) { size = p_size; - _queue_update(); + _request_update(); } Size2 PlaneMesh::get_size() const { @@ -944,7 +959,7 @@ Size2 PlaneMesh::get_size() const { void PlaneMesh::set_subdivide_width(const int p_subdivide) { subdivide_w = p_subdivide > 0 ? p_subdivide : 0; - _queue_update(); + _request_update(); } int PlaneMesh::get_subdivide_width() const { @@ -953,7 +968,7 @@ int PlaneMesh::get_subdivide_width() const { void PlaneMesh::set_subdivide_depth(const int p_subdivide) { subdivide_d = p_subdivide > 0 ? p_subdivide : 0; - _queue_update(true); //last property set, force update mesh + _request_update(); } int PlaneMesh::get_subdivide_depth() const { @@ -971,7 +986,7 @@ PlaneMesh::PlaneMesh() { PrismMesh */ -void PrismMesh::_create_mesh_array(Array &p_arr) { +void PrismMesh::_create_mesh_array(Array &p_arr) const { int i, j, prevrow, thisrow, point; float x, y, z; float onethird = 1.0 / 3.0; @@ -980,7 +995,6 @@ void PrismMesh::_create_mesh_array(Array &p_arr) { Vector3 start_pos = size * -0.5; // set our bounding box - set_aabb(Rect3(start_pos, size)); PoolVector points; PoolVector normals; @@ -1207,7 +1221,7 @@ void PrismMesh::_bind_methods() { void PrismMesh::set_left_to_right(const float p_left_to_right) { left_to_right = p_left_to_right; - _queue_update(); + _request_update(); } float PrismMesh::get_left_to_right() const { @@ -1216,7 +1230,7 @@ float PrismMesh::get_left_to_right() const { void PrismMesh::set_size(const Vector3 &p_size) { size = p_size; - _queue_update(); + _request_update(); } Vector3 PrismMesh::get_size() const { @@ -1225,7 +1239,7 @@ Vector3 PrismMesh::get_size() const { void PrismMesh::set_subdivide_width(const int p_divisions) { subdivide_w = p_divisions > 0 ? p_divisions : 0; - _queue_update(); + _request_update(); } int PrismMesh::get_subdivide_width() const { @@ -1234,7 +1248,7 @@ int PrismMesh::get_subdivide_width() const { void PrismMesh::set_subdivide_height(const int p_divisions) { subdivide_h = p_divisions > 0 ? p_divisions : 0; - _queue_update(); + _request_update(); } int PrismMesh::get_subdivide_height() const { @@ -1243,7 +1257,7 @@ int PrismMesh::get_subdivide_height() const { void PrismMesh::set_subdivide_depth(const int p_divisions) { subdivide_d = p_divisions > 0 ? p_divisions : 0; - _queue_update(true); //last property set, force update mesh + _request_update(); } int PrismMesh::get_subdivide_depth() const { @@ -1263,7 +1277,7 @@ PrismMesh::PrismMesh() { QuadMesh */ -void QuadMesh::_create_mesh_array(Array &p_arr) { +void QuadMesh::_create_mesh_array(Array &p_arr) const { PoolVector faces; PoolVector normals; PoolVector tangents; @@ -1312,19 +1326,17 @@ void QuadMesh::_bind_methods() { QuadMesh::QuadMesh() { primitive_type = PRIMITIVE_TRIANGLE_FAN; - _queue_update(true); } /** SphereMesh */ -void SphereMesh::_create_mesh_array(Array &p_arr) { +void SphereMesh::_create_mesh_array(Array &p_arr) const { int i, j, prevrow, thisrow, point; float x, y, z; // set our bounding box - set_aabb(Rect3(Vector3(-radius, height * -0.5, -radius), Vector3(radius * 2.0, height, radius * 2.0))); PoolVector points; PoolVector normals; @@ -1413,7 +1425,7 @@ void SphereMesh::_bind_methods() { void SphereMesh::set_radius(const float p_radius) { radius = p_radius; - _queue_update(); + _request_update(); } float SphereMesh::get_radius() const { @@ -1422,7 +1434,7 @@ float SphereMesh::get_radius() const { void SphereMesh::set_height(const float p_height) { height = p_height; - _queue_update(); + _request_update(); } float SphereMesh::get_height() const { @@ -1431,7 +1443,7 @@ float SphereMesh::get_height() const { void SphereMesh::set_radial_segments(const int p_radial_segments) { radial_segments = p_radial_segments > 4 ? p_radial_segments : 4; - _queue_update(); + _request_update(); } int SphereMesh::get_radial_segments() const { @@ -1440,7 +1452,7 @@ int SphereMesh::get_radial_segments() const { void SphereMesh::set_rings(const int p_rings) { rings = p_rings > 1 ? p_rings : 1; - _queue_update(); + _request_update(); } int SphereMesh::get_rings() const { @@ -1449,7 +1461,7 @@ int SphereMesh::get_rings() const { void SphereMesh::set_is_hemisphere(const bool p_is_hemisphere) { is_hemisphere = p_is_hemisphere; - _queue_update(true); //last property set, force update mesh + _request_update(); } bool SphereMesh::get_is_hemisphere() const { diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index 5e1387e864e..bcd5d30dd32 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -47,23 +47,20 @@ class PrimitiveMesh : public Mesh { private: RID mesh; - Rect3 aabb; + mutable Rect3 aabb; Ref material; - bool first_mesh; - bool cache_is_dirty; - void _update(); + mutable bool pending_request; + void _update() const; protected: Mesh::PrimitiveType primitive_type; static void _bind_methods(); - virtual void _create_mesh_array(Array &p_arr) = 0; - void _queue_update(bool p_first_mesh = false); //pretty bad hack to have the mesh built firt time parameters are set without delay - - void set_aabb(Rect3 p_aabb); + virtual void _create_mesh_array(Array &p_arr) const = 0; + void _request_update(); public: virtual int get_surface_count() const; @@ -99,7 +96,7 @@ private: protected: static void _bind_methods(); - virtual void _create_mesh_array(Array &p_arr); + virtual void _create_mesh_array(Array &p_arr) const; public: void set_radius(const float p_radius); @@ -132,7 +129,7 @@ private: protected: static void _bind_methods(); - virtual void _create_mesh_array(Array &p_arr); + virtual void _create_mesh_array(Array &p_arr) const; public: void set_size(const Vector3 &p_size); @@ -167,7 +164,7 @@ private: protected: static void _bind_methods(); - virtual void _create_mesh_array(Array &p_arr); + virtual void _create_mesh_array(Array &p_arr) const; public: void set_top_radius(const float p_radius); @@ -202,7 +199,7 @@ private: protected: static void _bind_methods(); - virtual void _create_mesh_array(Array &p_arr); + virtual void _create_mesh_array(Array &p_arr) const; public: void set_size(const Size2 &p_size); @@ -233,7 +230,7 @@ private: protected: static void _bind_methods(); - virtual void _create_mesh_array(Array &p_arr); + virtual void _create_mesh_array(Array &p_arr) const; public: void set_left_to_right(const float p_left_to_right); @@ -267,7 +264,7 @@ private: protected: static void _bind_methods(); - virtual void _create_mesh_array(Array &p_arr); + virtual void _create_mesh_array(Array &p_arr) const; public: QuadMesh(); @@ -289,7 +286,7 @@ private: protected: static void _bind_methods(); - virtual void _create_mesh_array(Array &p_arr); + virtual void _create_mesh_array(Array &p_arr) const; public: void set_radius(const float p_radius);