diff options
Diffstat (limited to 'editor')
28 files changed, 1027 insertions, 395 deletions
diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp index 3302b50103..7551214336 100644 --- a/editor/debugger/editor_debugger_node.cpp +++ b/editor/debugger/editor_debugger_node.cpp @@ -261,10 +261,12 @@ void EditorDebuggerNode::_notification(int p_what) { debugger_button->set_icon(Ref<Texture2D>()); } else { debugger_button->set_text(TTR("Debugger") + " (" + itos(error_count + warning_count) + ")"); - if (error_count == 0) { - debugger_button->set_icon(get_theme_icon("Warning", "EditorIcons")); - } else { + if (error_count >= 1 && warning_count >= 1) { + debugger_button->set_icon(get_theme_icon("ErrorWarning", "EditorIcons")); + } else if (error_count >= 1) { debugger_button->set_icon(get_theme_icon("Error", "EditorIcons")); + } else { + debugger_button->set_icon(get_theme_icon("Warning", "EditorIcons")); } } last_error_count = error_count; diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index 0fa62253c3..af79de2991 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -131,10 +131,12 @@ void ScriptEditorDebugger::update_tabs() { tabs->set_tab_icon(errors_tab->get_index(), Ref<Texture2D>()); } else { errors_tab->set_name(TTR("Errors") + " (" + itos(error_count + warning_count) + ")"); - if (error_count == 0) { - tabs->set_tab_icon(errors_tab->get_index(), get_theme_icon("Warning", "EditorIcons")); - } else { + if (error_count >= 1 && warning_count >= 1) { + tabs->set_tab_icon(errors_tab->get_index(), get_theme_icon("ErrorWarning", "EditorIcons")); + } else if (error_count >= 1) { tabs->set_tab_icon(errors_tab->get_index(), get_theme_icon("Error", "EditorIcons")); + } else { + tabs->set_tab_icon(errors_tab->get_index(), get_theme_icon("Warning", "EditorIcons")); } } } diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp index c89a7bcf23..78aed96363 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -63,11 +63,13 @@ void EditorLog::_notification(int p_what) { //button->set_icon(get_icon("Console","EditorIcons")); log->add_theme_font_override("normal_font", get_theme_font("output_source", "EditorFonts")); + log->add_theme_color_override("selection_color", get_theme_color("accent_color", "Editor") * Color(1, 1, 1, 0.4)); } else if (p_what == NOTIFICATION_THEME_CHANGED) { Ref<DynamicFont> df_output_code = get_theme_font("output_source", "EditorFonts"); if (df_output_code.is_valid()) { if (log != nullptr) { log->add_theme_font_override("normal_font", get_theme_font("output_source", "EditorFonts")); + log->add_theme_color_override("selection_color", get_theme_color("accent_color", "Editor") * Color(1, 1, 1, 0.4)); } } } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index c37ede4166..1b1ce4ec37 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -158,6 +158,7 @@ #include "editor/plugins/style_box_editor_plugin.h" #include "editor/plugins/text_editor.h" #include "editor/plugins/texture_editor_plugin.h" +#include "editor/plugins/texture_layered_editor_plugin.h" #include "editor/plugins/texture_region_editor_plugin.h" #include "editor/plugins/theme_editor_plugin.h" #include "editor/plugins/tile_map_editor_plugin.h" @@ -381,6 +382,8 @@ void EditorNode::_notification(int p_what) { RS::get_singleton()->shadows_quality_set(shadows_quality); RS::ShadowQuality directional_shadow_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/directional_shadow/soft_shadow_quality"))); RS::get_singleton()->directional_shadow_quality_set(directional_shadow_quality); + float probe_update_speed = GLOBAL_GET("rendering/lightmapper/probe_capture_update_speed"); + RS::get_singleton()->lightmap_set_probe_capture_update_speed(probe_update_speed); } ResourceImporterTexture::get_singleton()->update_imports(); @@ -713,7 +716,6 @@ void EditorNode::_sources_changed(bool p_exist) { // Reload the global shader variables, but this time // loading texures, as they are now properly imported. - print_line("done scanning, reload textures"); RenderingServer::get_singleton()->global_variables_load_settings(true); // Start preview thread now that it's safe. @@ -5678,7 +5680,7 @@ EditorNode::EditorNode() { import_texture.instance(); ResourceFormatImporter::get_singleton()->add_importer(import_texture); - /* Ref<ResourceImporterLayeredTexture> import_cubemap; + Ref<ResourceImporterLayeredTexture> import_cubemap; import_cubemap.instance(); import_cubemap->set_mode(ResourceImporterLayeredTexture::MODE_CUBEMAP); ResourceFormatImporter::get_singleton()->add_importer(import_cubemap); @@ -5692,7 +5694,12 @@ EditorNode::EditorNode() { import_cubemap_array.instance(); import_cubemap_array->set_mode(ResourceImporterLayeredTexture::MODE_CUBEMAP_ARRAY); ResourceFormatImporter::get_singleton()->add_importer(import_cubemap_array); -*/ + + /*Ref<ResourceImporterLayeredTexture> import_3d; + import_3d.instance(); + import_3d->set_mode(ResourceImporterLayeredTexture::MODE_3D); + ResourceFormatImporter::get_singleton()->add_importer(import_3d);*/ + Ref<ResourceImporterImage> import_image; import_image.instance(); ResourceFormatImporter::get_singleton()->add_importer(import_image); @@ -6663,7 +6670,7 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(SpriteFramesEditorPlugin(this))); add_editor_plugin(memnew(TextureRegionEditorPlugin(this))); add_editor_plugin(memnew(GIProbeEditorPlugin(this))); - //add_editor_plugin(memnew(BakedLightmapEditorPlugin(this))); + add_editor_plugin(memnew(BakedLightmapEditorPlugin(this))); add_editor_plugin(memnew(Path2DEditorPlugin(this))); add_editor_plugin(memnew(Path3DEditorPlugin(this))); add_editor_plugin(memnew(Line2DEditorPlugin(this))); @@ -6674,6 +6681,7 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(CollisionShape2DEditorPlugin(this))); add_editor_plugin(memnew(CurveEditorPlugin(this))); add_editor_plugin(memnew(TextureEditorPlugin(this))); + add_editor_plugin(memnew(TextureLayeredEditorPlugin(this))); add_editor_plugin(memnew(AudioStreamEditorPlugin(this))); add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor))); add_editor_plugin(memnew(Skeleton3DEditorPlugin(this))); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index d411b6dec4..c5772e0ea7 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -1611,7 +1611,7 @@ void EditorPropertyPlane::_value_changed(double val, const String &p_name) { p.normal.x = spin[0]->get_value(); p.normal.y = spin[1]->get_value(); p.normal.z = spin[2]->get_value(); - p.distance = spin[3]->get_value(); + p.d = spin[3]->get_value(); emit_changed(get_edited_property(), p, p_name); } @@ -1621,7 +1621,7 @@ void EditorPropertyPlane::update_property() { spin[0]->set_value(val.normal.x); spin[1]->set_value(val.normal.y); spin[2]->set_value(val.normal.z); - spin[3]->set_value(val.distance); + spin[3]->set_value(val.d); setting = false; } void EditorPropertyPlane::_notification(int p_what) { diff --git a/editor/icons/ErrorWarning.svg b/editor/icons/ErrorWarning.svg new file mode 100644 index 0000000000..72b5037e50 --- /dev/null +++ b/editor/icons/ErrorWarning.svg @@ -0,0 +1 @@ +<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><path d="m4 0c-2.216 0-4 1.784-4 4s1.784 4 4 4z" fill="#ff5d5d"/><path d="m4 .00000003c2.216 0 4 1.78399997 4 3.99999997s-1.784 4-4 4z" fill="#ffdd65"/></svg>
\ No newline at end of file diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp index 7e7a982501..697ddfba96 100644 --- a/editor/import/editor_import_collada.cpp +++ b/editor/import/editor_import_collada.cpp @@ -766,7 +766,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me Vector3 tangent = Vector3(tangent_src->array[tangent_pos + 0], tangent_src->array[tangent_pos + 1], tangent_src->array[tangent_pos + 2]); vertex.tangent.normal = tangent; - vertex.tangent.distance = vertex.normal.cross(tangent).dot(binormal) > 0 ? 1 : -1; + vertex.tangent.d = vertex.normal.cross(tangent).dot(binormal) > 0 ? 1 : -1; } } @@ -794,7 +794,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me #ifndef NO_UP_AXIS_SWAP if (collada.state.up_axis == Vector3::AXIS_Z) { - Vector3 bn = vertex.normal.cross(vertex.tangent.normal) * vertex.tangent.distance; + Vector3 bn = vertex.normal.cross(vertex.tangent.normal) * vertex.tangent.d; SWAP(vertex.vertex.z, vertex.vertex.y); vertex.vertex.z = -vertex.vertex.z; @@ -805,7 +805,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me SWAP(bn.z, bn.y); bn.z = -bn.z; - vertex.tangent.distance = vertex.normal.cross(vertex.tangent.normal).dot(bn) > 0 ? 1 : -1; + vertex.tangent.d = vertex.normal.cross(vertex.tangent.normal).dot(bn) > 0 ? 1 : -1; } #endif diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp index a4cbc81b26..c46cf4c1a8 100644 --- a/editor/import/resource_importer_layered_texture.cpp +++ b/editor/import/resource_importer_layered_texture.cpp @@ -36,9 +36,9 @@ #include "core/io/image_loader.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" +#include "resource_importer_texture.h" #include "scene/resources/texture.h" -#if 0 String ResourceImporterLayeredTexture::get_importer_name() const { switch (mode) { @@ -51,6 +51,9 @@ String ResourceImporterLayeredTexture::get_importer_name() const { case MODE_CUBEMAP_ARRAY: { return "cubemap_array_texture"; } break; + case MODE_3D: { + return "cubemap_3d_texture"; + } break; } ERR_FAIL_V(""); @@ -68,6 +71,9 @@ String ResourceImporterLayeredTexture::get_visible_name() const { case MODE_CUBEMAP_ARRAY: { return "CubemapArray"; } break; + case MODE_3D: { + return "3D"; + } break; } ERR_FAIL_V(""); @@ -79,13 +85,16 @@ void ResourceImporterLayeredTexture::get_recognized_extensions(List<String> *p_e String ResourceImporterLayeredTexture::get_save_extension() const { switch (mode) { case MODE_CUBEMAP: { - return "cube"; + return "scube"; } break; case MODE_2D_ARRAY: { - return "tex2darr"; + return "stexarray"; } break; case MODE_CUBEMAP_ARRAY: { - return "cubearr"; + return "scubearray"; + } break; + case MODE_3D: { + return "stex3d"; } break; } @@ -96,13 +105,16 @@ String ResourceImporterLayeredTexture::get_resource_type() const { switch (mode) { case MODE_CUBEMAP: { - return "Cubemap"; + return "StreamCubemap"; } break; case MODE_2D_ARRAY: { - return "Texture2DArray"; + return "StreamTexture2DArray"; } break; case MODE_CUBEMAP_ARRAY: { - return "CubemapArray"; + return "StreamCubemapArray"; + } break; + case MODE_3D: { + return "StreamTexture3D"; } break; } ERR_FAIL_V(String()); @@ -110,6 +122,9 @@ String ResourceImporterLayeredTexture::get_resource_type() const { bool ResourceImporterLayeredTexture::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const { + if (p_option == "compress/lossy_quality" && p_options.has("compress/mode")) { + return int(p_options["compress/mode"]) == COMPRESS_LOSSY; + } return true; } @@ -123,138 +138,109 @@ String ResourceImporterLayeredTexture::get_preset_name(int p_idx) const { void ResourceImporterLayeredTexture::get_import_options(List<ImportOption> *r_options, int p_preset) const { - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless,Video RAM,Uncompressed", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1)); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress/no_bptc_if_rgb"), false)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless,Lossy,Video RAM,Uncompressed,Basis Universal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1)); + r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "compress/lossy_quality", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.7)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/hdr_compression", PROPERTY_HINT_ENUM, "Disabled,Opaque Only,Always"), 1)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/bptc_ldr", PROPERTY_HINT_ENUM, "Disabled,Enabled,RGBA Only"), 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/channel_pack", PROPERTY_HINT_ENUM, "sRGB Friendly,Optimized"), 0)); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "flags/mipmaps"), true)); - if (mode == MODE_2D_ARRAY) { + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "mipmaps/generate"), true)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "mipmaps/limit", PROPERTY_HINT_RANGE, "-1,256"), -1)); + + if (mode == MODE_2D_ARRAY || mode == MODE_3D) { r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/horizontal", PROPERTY_HINT_RANGE, "1,256,1"), 8)); - } - if (mode == MODE_2D_ARRAY || mode == MODE_CUBEMAP_ARRAY) { r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/vertical", PROPERTY_HINT_RANGE, "1,256,1"), 8)); } -} - -void ResourceImporterLayeredTexture::_save_tex(const Vector<Ref<Image> > &p_images, const String &p_to_path, int p_compress_mode, Image::CompressMode p_vram_compression, bool p_mipmaps) { - - FileAccess *f = FileAccess::open(p_to_path, FileAccess::WRITE); - f->store_8('G'); - f->store_8('D'); - switch (mode) { - case MODE_2D_ARRAY: f->store_8('A'); break; - case MODE_CUBEMAP: f->store_8('C'); break; - case MODE_CUBEMAP_ARRAY: f->store_8('X'); break; - } - - f->store_8('T'); //godot streamable texture - - f->store_32(p_images[0]->get_width()); - f->store_32(p_images[0]->get_height()); - f->store_32(p_images.size()); //depth - uint32_t flags = 0; - if (p_mipmaps) { - flags |= TEXTURE_FLAGS_MIPMAPS; - } - f->store_32(flags); - if (p_compress_mode != COMPRESS_VIDEO_RAM) { - //vram needs to do a first compression to tell what the format is, for the rest its ok - f->store_32(p_images[0]->get_format()); - f->store_32(p_compress_mode); // 0 - lossless (PNG), 1 - vram, 2 - uncompressed + if (mode == MODE_CUBEMAP || mode == MODE_CUBEMAP_ARRAY) { + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/arrangement", PROPERTY_HINT_ENUM, "1x6,2x3,3x2,6x1"), 1)); + if (mode == MODE_CUBEMAP_ARRAY) { + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/layout", PROPERTY_HINT_ENUM, "Horizontal,Vertical"), 1)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/amount", PROPERTY_HINT_RANGE, "1,1024,1,or_greater"), 1)); + } } +} - if ((p_compress_mode == COMPRESS_LOSSLESS) && p_images[0]->get_format() > Image::FORMAT_RGBA8) { - p_compress_mode = COMPRESS_UNCOMPRESSED; //these can't go as lossy - } +void ResourceImporterLayeredTexture::_save_tex(Vector<Ref<Image>> p_images, const String &p_to_path, int p_compress_mode, float p_lossy, Image::CompressMode p_vram_compression, Image::CompressSource p_csource, Image::UsedChannels used_channels, bool p_mipmaps, bool p_force_po2) { for (int i = 0; i < p_images.size(); i++) { - switch (p_compress_mode) { - case COMPRESS_LOSSLESS: { - - Ref<Image> image = p_images[i]->duplicate(); - if (p_mipmaps) { - image->generate_mipmaps(); - } else { - image->clear_mipmaps(); - } - - int mmc = image->get_mipmap_count() + 1; - f->store_32(mmc); - - for (int j = 0; j < mmc; j++) { - - if (j > 0) { - image->shrink_x2(); - } - - Vector<uint8_t> data = Image::lossless_packer(image); - int data_len = data.size(); - f->store_32(data_len); - - const uint8_t* r = data.ptr(); - f->store_buffer(r.ptr(), data_len); - } - - } break; - case COMPRESS_VIDEO_RAM: { - - Ref<Image> image = p_images[i]->duplicate(); - image->generate_mipmaps(false); - - Image::CompressSource csource = Image::COMPRESS_SOURCE_LAYERED; - image->compress(p_vram_compression, csource, 0.7); - - if (i == 0) { - //hack so we can properly tell the format - f->store_32(image->get_format()); - f->store_32(p_compress_mode); // 0 - lossless (PNG), 1 - vram, 2 - uncompressed - } - - Vector<uint8_t> data = image->get_data(); - int dl = data.size(); - - const uint8_t* r = data.ptr(); - f->store_buffer(r.ptr(), dl); - } break; - case COMPRESS_UNCOMPRESSED: { - - Ref<Image> image = p_images[i]->duplicate(); + if (p_force_po2) { + p_images.write[i]->resize_to_po2(); + } - if (p_mipmaps) { - image->generate_mipmaps(); - } else { - image->clear_mipmaps(); - } + if (p_mipmaps) { + p_images.write[i]->generate_mipmaps(); + } else { + p_images.write[i]->clear_mipmaps(); + } + } - Vector<uint8_t> data = image->get_data(); - int dl = data.size(); + FileAccessRef f = FileAccess::open(p_to_path, FileAccess::WRITE); + f->store_8('G'); + f->store_8('S'); + f->store_8('T'); + f->store_8('L'); - const uint8_t* r = data.ptr(); + f->store_32(StreamTextureLayered::FORMAT_VERSION); + f->store_32(p_images.size()); + f->store_32(mode); + f->store_32(0); //dataformat + f->store_32(0); //mipmap limit - f->store_buffer(r.ptr(), dl); + //reserverd + f->store_32(0); + f->store_32(0); + f->store_32(0); - } break; - } + for (int i = 0; i < p_images.size(); i++) { + ResourceImporterTexture::save_to_stex_format(f, p_images[i], ResourceImporterTexture::CompressMode(p_compress_mode), used_channels, p_vram_compression, p_lossy); } - memdelete(f); + f->close(); } Error ResourceImporterLayeredTexture::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { int compress_mode = p_options["compress/mode"]; - int no_bptc_if_rgb = p_options["compress/no_bptc_if_rgb"]; - bool mipmaps = p_options["flags/mipmaps"]; + float lossy = p_options["compress/lossy_quality"]; + int hdr_compression = p_options["compress/hdr_compression"]; + int bptc_ldr = p_options["compress/bptc_ldr"]; + bool mipmaps = p_options["mipmaps/generate"]; + //bool mipmap_limit = p_options["mipmaps/limit"]; + int channel_pack = p_options["compress/channel_pack"]; int hslices = (p_options.has("slices/horizontal")) ? int(p_options["slices/horizontal"]) : 0; int vslices = (p_options.has("slices/vertical")) ? int(p_options["slices/vertical"]) : 0; + int arrangement = (p_options.has("slices/arrangement")) ? int(p_options["slices/arrangement"]) : 0; + int layout = (p_options.has("slices/layout")) ? int(p_options["slices/layout"]) : 0; + int amount = (p_options.has("slices/amount")) ? int(p_options["slices/amount"]) : 0; + + if (mode == MODE_CUBEMAP || mode == MODE_CUBEMAP_ARRAY) { + switch (arrangement) { + case CUBEMAP_FORMAT_1X6: { + hslices = 1; + vslices = 6; + } break; + case CUBEMAP_FORMAT_2X3: { + hslices = 2; + vslices = 3; + } break; + case CUBEMAP_FORMAT_3X2: { + hslices = 3; + vslices = 2; + } break; + case CUBEMAP_FORMAT_6X1: { + hslices = 6; + vslices = 1; + } break; + } - if (mode == MODE_CUBEMAP) { - hslices = 3; - vslices = 2; - } else if (mode == MODE_CUBEMAP_ARRAY) { - hslices = 3; - vslices *= 2; //put cubemaps vertically + if (mode == MODE_CUBEMAP_ARRAY) { + if (layout == 0) { + hslices *= amount; + } else { + vslices *= amount; + } + } } Ref<Image> image; @@ -263,28 +249,40 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const if (err != OK) return err; - if (compress_mode == COMPRESS_VIDEO_RAM) { - mipmaps = true; + if (compress_mode == COMPRESS_BASIS_UNIVERSAL && image->get_format() >= Image::FORMAT_RF) { + //basis universal does not support float formats, fall back + compress_mode = COMPRESS_VRAM_COMPRESSED; } - Vector<Ref<Image> > slices; - - int slice_w = image->get_width() / hslices; - int slice_h = image->get_height() / vslices; + if (compress_mode == COMPRESS_VRAM_COMPRESSED) { + mipmaps = true; + } //optimize - if (compress_mode == COMPRESS_VIDEO_RAM) { + if (compress_mode == COMPRESS_VRAM_COMPRESSED) { //if using video ram, optimize if (channel_pack == 0) { //remove alpha if not needed, so compression is more efficient if (image->get_format() == Image::FORMAT_RGBA8 && !image->detect_alpha()) { image->convert(Image::FORMAT_RGB8); } - } else { + } else if (image->get_format() < Image::FORMAT_RGBA8) { image->optimize_channels(); } } + Image::CompressSource csource = Image::COMPRESS_SOURCE_GENERIC; + if (channel_pack == 0) { + csource = Image::COMPRESS_SOURCE_SRGB; + } + + Image::UsedChannels used_channels = image->detect_used_channels(csource); + + Vector<Ref<Image>> slices; + + int slice_w = image->get_width() / hslices; + int slice_h = image->get_height() / vslices; + for (int i = 0; i < vslices; i++) { for (int j = 0; j < hslices; j++) { int x = slice_w * j; @@ -301,58 +299,82 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const String extension = get_save_extension(); Array formats_imported; - if (compress_mode == COMPRESS_VIDEO_RAM) { + if (compress_mode == COMPRESS_VRAM_COMPRESSED) { //must import in all formats, in order of priority (so platform choses the best supported one. IE, etc2 over etc). //Android, GLES 2.x bool ok_on_pc = false; - bool encode_bptc = false; + bool is_hdr = (image->get_format() >= Image::FORMAT_RF && image->get_format() <= Image::FORMAT_RGBE9995); + bool is_ldr = (image->get_format() >= Image::FORMAT_L8 && image->get_format() <= Image::FORMAT_RGB565); + bool can_bptc = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_bptc"); + bool can_s3tc = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc"); - if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_bptc")) { + if (can_bptc) { + formats_imported.push_back("bptc"); //needs to be aded anyway + } + bool can_compress_hdr = hdr_compression > 0; + + if (is_hdr && can_compress_hdr) { + + if (used_channels == Image::USED_CHANNELS_LA || used_channels == Image::USED_CHANNELS_RGBA) { + //can compress hdr, but hdr with alpha is not compressible - encode_bptc = true; + if (hdr_compression == 2) { + //but user selected to compress hdr anyway, so force an alpha-less format. + if (image->get_format() == Image::FORMAT_RGBAF) { + for (int i = 0; i < slices.size(); i++) { + slices.write[i]->convert(Image::FORMAT_RGBF); + } - if (no_bptc_if_rgb) { - Image::UsedChannels channels = image->detect_used_channels(); - if (channels != Image::USED_CHANNELS_LA && channels != Image::USED_CHANNELS_RGBA) { - encode_bptc = false; + } else if (image->get_format() == Image::FORMAT_RGBAH) { + for (int i = 0; i < slices.size(); i++) { + slices.write[i]->convert(Image::FORMAT_RGBH); + } + } + } else { + can_compress_hdr = false; } } - formats_imported.push_back("bptc"); - } + if (can_compress_hdr) { - if (encode_bptc) { + if (!can_bptc) { - _save_tex(slices, p_save_path + ".bptc." + extension, compress_mode, Image::COMPRESS_BPTC, mipmaps); - r_platform_variants->push_back("bptc"); - ok_on_pc = true; + //default to rgbe + if (image->get_format() != Image::FORMAT_RGBE9995) { + for (int i = 0; i < slices.size(); i++) { + slices.write[i]->convert(Image::FORMAT_RGBE9995); + } + } + } + } else { + can_bptc = false; + } } - if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc")) { + if (is_ldr && can_bptc) { + if (bptc_ldr == 0 || (bptc_ldr == 1 && !(used_channels == Image::USED_CHANNELS_LA || used_channels == Image::USED_CHANNELS_RGBA))) { + can_bptc = false; + } + } - _save_tex(slices, p_save_path + ".s3tc." + extension, compress_mode, Image::COMPRESS_S3TC, mipmaps); + if (can_bptc || can_s3tc) { + _save_tex(slices, p_save_path + ".s3tc." + extension, compress_mode, lossy, can_bptc ? Image::COMPRESS_BPTC : Image::COMPRESS_S3TC, csource, used_channels, mipmaps, false); r_platform_variants->push_back("s3tc"); - ok_on_pc = true; formats_imported.push_back("s3tc"); + ok_on_pc = true; } if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) { - _save_tex(slices, p_save_path + ".etc2." + extension, compress_mode, Image::COMPRESS_ETC2, mipmaps); + _save_tex(slices, p_save_path + ".etc2." + extension, compress_mode, lossy, Image::COMPRESS_ETC2, csource, used_channels, mipmaps, true); r_platform_variants->push_back("etc2"); formats_imported.push_back("etc2"); } - if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc")) { - _save_tex(slices, p_save_path + ".etc." + extension, compress_mode, Image::COMPRESS_ETC, mipmaps); - r_platform_variants->push_back("etc"); - formats_imported.push_back("etc"); - } - if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc")) { - _save_tex(slices, p_save_path + ".pvrtc." + extension, compress_mode, Image::COMPRESS_PVRTC4, mipmaps); + _save_tex(slices, p_save_path + ".etc2." + extension, compress_mode, lossy, Image::COMPRESS_ETC2, csource, used_channels, mipmaps, true); r_platform_variants->push_back("pvrtc"); formats_imported.push_back("pvrtc"); } @@ -362,12 +384,12 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const } } else { //import normally - _save_tex(slices, p_save_path + "." + extension, compress_mode, Image::COMPRESS_S3TC /*this is ignored */, mipmaps); + _save_tex(slices, p_save_path + "." + extension, compress_mode, lossy, Image::COMPRESS_S3TC /* IGNORED */, csource, used_channels, mipmaps, false); } if (r_metadata) { Dictionary metadata; - metadata["vram_texture"] = compress_mode == COMPRESS_VIDEO_RAM; + metadata["vram_texture"] = compress_mode == COMPRESS_VRAM_COMPRESSED; if (formats_imported.size()) { metadata["imported_formats"] = formats_imported; } @@ -448,4 +470,3 @@ ResourceImporterLayeredTexture::ResourceImporterLayeredTexture() { ResourceImporterLayeredTexture::~ResourceImporterLayeredTexture() { } -#endif diff --git a/editor/import/resource_importer_layered_texture.h b/editor/import/resource_importer_layered_texture.h index 40e5c9023e..18eaf31f6b 100644 --- a/editor/import/resource_importer_layered_texture.h +++ b/editor/import/resource_importer_layered_texture.h @@ -28,7 +28,6 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#if 0 /*************************************************************************/ /* resource_importer_layered_texture.h */ /*************************************************************************/ @@ -65,16 +64,24 @@ #include "core/image.h" #include "core/io/resource_importer.h" - -class StreamTexture; +class StreamTexture2D; class ResourceImporterLayeredTexture : public ResourceImporter { GDCLASS(ResourceImporterLayeredTexture, ResourceImporter); + public: enum Mode { - MODE_CUBEMAP, MODE_2D_ARRAY, - MODE_CUBEMAP_ARRAY + MODE_CUBEMAP, + MODE_CUBEMAP_ARRAY, + MODE_3D, + }; + + enum CubemapFormat { + CUBEMAP_FORMAT_1X6, + CUBEMAP_FORMAT_2X3, + CUBEMAP_FORMAT_3X2, + CUBEMAP_FORMAT_6X1, }; enum TextureFlags { @@ -86,9 +93,9 @@ private: static const char *compression_formats[]; protected: - static void _texture_reimport_srgb(const Ref<StreamTexture> &p_tex); - static void _texture_reimport_3d(const Ref<StreamTexture> &p_tex); - static void _texture_reimport_normal(const Ref<StreamTexture> &p_tex); + static void _texture_reimport_srgb(const Ref<StreamTexture2D> &p_tex); + static void _texture_reimport_3d(const Ref<StreamTexture2D> &p_tex); + static void _texture_reimport_normal(const Ref<StreamTexture2D> &p_tex); static ResourceImporterLayeredTexture *singleton; @@ -102,8 +109,10 @@ public: enum CompressMode { COMPRESS_LOSSLESS, - COMPRESS_VIDEO_RAM, - COMPRESS_UNCOMPRESSED + COMPRESS_LOSSY, + COMPRESS_VRAM_COMPRESSED, + COMPRESS_VRAM_UNCOMPRESSED, + COMPRESS_BASIS_UNIVERSAL }; virtual int get_preset_count() const; @@ -112,7 +121,7 @@ public: virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; - void _save_tex(const Vector<Ref<Image> > &p_images, const String &p_to_path, int p_compress_mode, Image::CompressMode p_vram_compression, bool p_mipmaps); + void _save_tex(Vector<Ref<Image>> p_images, const String &p_to_path, int p_compress_mode, float p_lossy, Image::CompressMode p_vram_compression, Image::CompressSource p_csource, Image::UsedChannels used_channels, bool p_mipmaps, bool p_force_po2); virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr); @@ -126,6 +135,5 @@ public: ResourceImporterLayeredTexture(); ~ResourceImporterLayeredTexture(); }; -#endif // RESOURCE_IMPORTER_LAYERED_TEXTURE_H -#endif +#endif // RESOURCE_IMPORTER_LAYERED_TEXTURE_H diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index e7f87acd03..b9341b1fb6 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -354,7 +354,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh> if (p_light_bake_mode != LIGHT_BAKE_DISABLED) { - mi->set_flag(GeometryInstance3D::FLAG_USE_BAKED_LIGHT, true); + mi->set_gi_mode(GeometryInstance3D::GI_MODE_BAKED); } } @@ -955,7 +955,7 @@ void ResourceImporterScene::_find_meshes(Node *p_node, Map<Ref<ArrayMesh>, Trans Transform transform; while (s) { transform = transform * s->get_transform(); - s = s->get_parent_spatial(); + s = Object::cast_to<Node3D>(s->get_parent()); } meshes[mesh] = transform; @@ -1358,8 +1358,9 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p scene->set_script(Variant(root_script)); } + float root_scale = 1.0; if (Object::cast_to<Node3D>(scene)) { - float root_scale = p_options["nodes/root_scale"]; + root_scale = p_options["nodes/root_scale"]; Object::cast_to<Node3D>(scene)->scale(Vector3(root_scale, root_scale, root_scale)); } diff --git a/editor/import/resource_importer_shader_file.cpp b/editor/import/resource_importer_shader_file.cpp index 3a6215e035..f085341969 100644 --- a/editor/import/resource_importer_shader_file.cpp +++ b/editor/import/resource_importer_shader_file.cpp @@ -103,7 +103,7 @@ Error ResourceImporterShaderFile::import(const String &p_source_file, const Stri Ref<RDShaderFile> shader_file; shader_file.instance(); String base_path = p_source_file.get_base_dir(); - err = shader_file->parse_versions_from_text(file_txt, _include_function, &base_path); + err = shader_file->parse_versions_from_text(file_txt, "", _include_function, &base_path); if (err != OK) { if (!ShaderFileEditor::singleton->is_visible_in_tree()) { diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index f8ed9304b6..111eab78b4 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -36,7 +36,7 @@ #include "editor/editor_file_system.h" #include "editor/editor_node.h" -void ResourceImporterTexture::_texture_reimport_roughness(const Ref<StreamTexture> &p_tex, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_channel) { +void ResourceImporterTexture::_texture_reimport_roughness(const Ref<StreamTexture2D> &p_tex, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_channel) { MutexLock lock(singleton->mutex); @@ -51,7 +51,7 @@ void ResourceImporterTexture::_texture_reimport_roughness(const Ref<StreamTextur singleton->make_flags[path].normal_path_for_roughness = p_normal_path; } -void ResourceImporterTexture::_texture_reimport_3d(const Ref<StreamTexture> &p_tex) { +void ResourceImporterTexture::_texture_reimport_3d(const Ref<StreamTexture2D> &p_tex) { MutexLock lock(singleton->mutex); @@ -64,7 +64,7 @@ void ResourceImporterTexture::_texture_reimport_3d(const Ref<StreamTexture> &p_t singleton->make_flags[path].flags |= MAKE_3D_FLAG; } -void ResourceImporterTexture::_texture_reimport_normal(const Ref<StreamTexture> &p_tex) { +void ResourceImporterTexture::_texture_reimport_normal(const Ref<StreamTexture2D> &p_tex) { MutexLock lock(singleton->mutex); @@ -157,7 +157,7 @@ String ResourceImporterTexture::get_save_extension() const { String ResourceImporterTexture::get_resource_type() const { - return "StreamTexture"; + return "StreamTexture2D"; } bool ResourceImporterTexture::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const { @@ -207,8 +207,8 @@ void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options, r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless,Lossy,VRAM Compressed,VRAM Uncompressed,Basis Universal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), p_preset == PRESET_3D ? 2 : 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "compress/lossy_quality", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.7)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/hdr_mode", PROPERTY_HINT_ENUM, "Enabled,Force RGBE"), 0)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/bptc_ldr", PROPERTY_HINT_ENUM, "Enabled,RGBA Only"), 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/hdr_compression", PROPERTY_HINT_ENUM, "Disabled,Opaque Only,Always"), 1)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/bptc_ldr", PROPERTY_HINT_ENUM, "Disabled,Enabled,RGBA Only"), 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/normal_map", PROPERTY_HINT_ENUM, "Detect,Enable,Disabled"), 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/channel_pack", PROPERTY_HINT_ENUM, "sRGB Friendly,Optimized"), 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/streamed"), false)); @@ -225,12 +225,12 @@ void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options, r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "svg/scale", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 1.0)); } -void ResourceImporterTexture::save_to_stex_format(FileAccess *f, const Ref<Image> &p_image, CompressMode p_compress_mode, Image::UsedChannels p_channels, Image::CompressMode p_compress_format, float p_lossy_quality, bool p_force_rgbe) { +void ResourceImporterTexture::save_to_stex_format(FileAccess *f, const Ref<Image> &p_image, CompressMode p_compress_mode, Image::UsedChannels p_channels, Image::CompressMode p_compress_format, float p_lossy_quality) { switch (p_compress_mode) { case COMPRESS_LOSSLESS: { - f->store_32(StreamTexture::DATA_FORMAT_LOSSLESS); + f->store_32(StreamTexture2D::DATA_FORMAT_LOSSLESS); f->store_16(p_image->get_width()); f->store_16(p_image->get_height()); f->store_32(p_image->get_mipmap_count()); @@ -249,7 +249,7 @@ void ResourceImporterTexture::save_to_stex_format(FileAccess *f, const Ref<Image } break; case COMPRESS_LOSSY: { - f->store_32(StreamTexture::DATA_FORMAT_LOSSY); + f->store_32(StreamTexture2D::DATA_FORMAT_LOSSY); f->store_16(p_image->get_width()); f->store_16(p_image->get_height()); f->store_32(p_image->get_mipmap_count()); @@ -269,13 +269,9 @@ void ResourceImporterTexture::save_to_stex_format(FileAccess *f, const Ref<Image Ref<Image> image = p_image->duplicate(); - if (p_force_rgbe && image->get_format() >= Image::FORMAT_RF && image->get_format() < Image::FORMAT_RGBE9995) { - image->convert(Image::FORMAT_RGBE9995); - } else { - image->compress_from_channels(p_compress_format, p_channels, p_lossy_quality); - } + image->compress_from_channels(p_compress_format, p_channels, p_lossy_quality); - f->store_32(StreamTexture::DATA_FORMAT_IMAGE); + f->store_32(StreamTexture2D::DATA_FORMAT_IMAGE); f->store_16(image->get_width()); f->store_16(image->get_height()); f->store_32(image->get_mipmap_count()); @@ -288,7 +284,7 @@ void ResourceImporterTexture::save_to_stex_format(FileAccess *f, const Ref<Image } break; case COMPRESS_VRAM_UNCOMPRESSED: { - f->store_32(StreamTexture::DATA_FORMAT_IMAGE); + f->store_32(StreamTexture2D::DATA_FORMAT_IMAGE); f->store_16(p_image->get_width()); f->store_16(p_image->get_height()); f->store_32(p_image->get_mipmap_count()); @@ -303,7 +299,7 @@ void ResourceImporterTexture::save_to_stex_format(FileAccess *f, const Ref<Image } break; case COMPRESS_BASIS_UNIVERSAL: { - f->store_32(StreamTexture::DATA_FORMAT_BASIS_UNIVERSAL); + f->store_32(StreamTexture2D::DATA_FORMAT_BASIS_UNIVERSAL); f->store_16(p_image->get_width()); f->store_16(p_image->get_height()); f->store_32(p_image->get_mipmap_count()); @@ -322,7 +318,7 @@ void ResourceImporterTexture::save_to_stex_format(FileAccess *f, const Ref<Image } } -void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String &p_to_path, CompressMode p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, bool p_streamable, bool p_detect_3d, bool p_detect_roughness, bool p_force_rgbe, bool p_detect_normal, bool p_force_normal, bool p_srgb_friendly, bool p_force_po2_for_compressed, uint32_t p_limit_mipmap, const Ref<Image> &p_normal, Image::RoughnessChannel p_roughness_channel) { +void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String &p_to_path, CompressMode p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, bool p_streamable, bool p_detect_3d, bool p_detect_roughness, bool p_detect_normal, bool p_force_normal, bool p_srgb_friendly, bool p_force_po2_for_compressed, uint32_t p_limit_mipmap, const Ref<Image> &p_normal, Image::RoughnessChannel p_roughness_channel) { FileAccess *f = FileAccess::open(p_to_path, FileAccess::WRITE); f->store_8('G'); @@ -331,22 +327,22 @@ void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String f->store_8('2'); //godot streamable texture 2D //format version - f->store_32(StreamTexture::FORMAT_VERSION); + f->store_32(StreamTexture2D::FORMAT_VERSION); //texture may be resized later, so original size must be saved first f->store_32(p_image->get_width()); f->store_32(p_image->get_height()); uint32_t flags = 0; if (p_streamable) - flags |= StreamTexture::FORMAT_BIT_STREAM; + flags |= StreamTexture2D::FORMAT_BIT_STREAM; if (p_mipmaps) - flags |= StreamTexture::FORMAT_BIT_HAS_MIPMAPS; //mipmaps bit + flags |= StreamTexture2D::FORMAT_BIT_HAS_MIPMAPS; //mipmaps bit if (p_detect_3d) - flags |= StreamTexture::FORMAT_BIT_DETECT_3D; + flags |= StreamTexture2D::FORMAT_BIT_DETECT_3D; if (p_detect_roughness) - flags |= StreamTexture::FORMAT_BIT_DETECT_ROUGNESS; + flags |= StreamTexture2D::FORMAT_BIT_DETECT_ROUGNESS; if (p_detect_normal) - flags |= StreamTexture::FORMAT_BIT_DETECT_NORMAL; + flags |= StreamTexture2D::FORMAT_BIT_DETECT_NORMAL; f->store_32(flags); f->store_32(p_limit_mipmap); @@ -385,10 +381,6 @@ void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String image->generate_mipmap_roughness(p_roughness_channel, p_normal); } - if (p_force_rgbe && image->get_format() >= Image::FORMAT_RF && image->get_format() < Image::FORMAT_RGBE9995) { - image->convert(Image::FORMAT_RGBE9995); - } - Image::CompressSource csource = Image::COMPRESS_SOURCE_GENERIC; if (p_force_normal) { csource = Image::COMPRESS_SOURCE_NORMAL; @@ -398,7 +390,7 @@ void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String Image::UsedChannels used_channels = image->detect_used_channels(csource); - save_to_stex_format(f, image, p_compress_mode, used_channels, p_vram_compression, p_lossy_quality, p_force_rgbe); + save_to_stex_format(f, image, p_compress_mode, used_channels, p_vram_compression, p_lossy_quality); memdelete(f); } @@ -418,7 +410,7 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String bool hdr_as_srgb = p_options["process/HDR_as_SRGB"]; int normal = p_options["compress/normal_map"]; float scale = p_options["svg/scale"]; - bool force_rgbe = int(p_options["compress/hdr_mode"]) == 1; + int hdr_compression = p_options["compress/hdr_compression"]; int bptc_ldr = p_options["compress/bptc_ldr"]; int roughness = p_options["roughness/mode"]; String normal_map = p_options["roughness/src_normal"]; @@ -501,30 +493,49 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String bool can_s3tc = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc"); if (can_bptc) { - Image::UsedChannels channels = image->detect_used_channels(); - if (is_hdr) { + //add to the list anyway + formats_imported.push_back("bptc"); + } - if (channels == Image::USED_CHANNELS_LA || channels == Image::USED_CHANNELS_RGBA) { - can_bptc = false; + bool can_compress_hdr = hdr_compression > 0; + bool has_alpha = image->detect_alpha() != Image::ALPHA_NONE; + + if (is_hdr && can_compress_hdr) { + + if (has_alpha) { + //can compress hdr, but hdr with alpha is not compressible + if (hdr_compression == 2) { + //but user selected to compress hdr anyway, so force an alpha-less format. + if (image->get_format() == Image::FORMAT_RGBAF) { + image->convert(Image::FORMAT_RGBF); + } else if (image->get_format() == Image::FORMAT_RGBAH) { + image->convert(Image::FORMAT_RGBH); + } + } else { + can_compress_hdr = false; } - } else if (is_ldr) { + } - //handle "RGBA Only" setting - if (bptc_ldr == 1 && channels != Image::USED_CHANNELS_LA && channels != Image::USED_CHANNELS_RGBA) { - can_bptc = false; + if (can_compress_hdr) { + if (!can_bptc) { + //fallback to RGBE99995 + if (image->get_format() != Image::FORMAT_RGBE9995) { + image->convert(Image::FORMAT_RGBE9995); + } } + } else { + can_bptc = false; } - - formats_imported.push_back("bptc"); } - if (!can_bptc && is_hdr && !force_rgbe) { - //convert to ldr if this can't be stored hdr - image->convert(Image::FORMAT_RGBA8); + if (is_ldr && can_bptc) { + if (bptc_ldr == 0 || (bptc_ldr == 1 && !has_alpha)) { + can_bptc = false; + } } if (can_bptc || can_s3tc) { - _save_stex(image, p_save_path + ".s3tc.stex", compress_mode, lossy, can_bptc ? Image::COMPRESS_BPTC : Image::COMPRESS_S3TC, mipmaps, stream, detect_3d, detect_roughness, force_rgbe, detect_normal, force_normal, srgb_friendly_pack, false, mipmap_limit, normal_image, roughness_channel); + _save_stex(image, p_save_path + ".s3tc.stex", compress_mode, lossy, can_bptc ? Image::COMPRESS_BPTC : Image::COMPRESS_S3TC, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, false, mipmap_limit, normal_image, roughness_channel); r_platform_variants->push_back("s3tc"); formats_imported.push_back("s3tc"); ok_on_pc = true; @@ -532,20 +543,20 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) { - _save_stex(image, p_save_path + ".etc2.stex", compress_mode, lossy, Image::COMPRESS_ETC2, mipmaps, stream, detect_3d, detect_roughness, force_rgbe, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel); + _save_stex(image, p_save_path + ".etc2.stex", compress_mode, lossy, Image::COMPRESS_ETC2, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel); r_platform_variants->push_back("etc2"); formats_imported.push_back("etc2"); } if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc")) { - _save_stex(image, p_save_path + ".etc.stex", compress_mode, lossy, Image::COMPRESS_ETC, mipmaps, stream, detect_3d, detect_roughness, force_rgbe, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel); + _save_stex(image, p_save_path + ".etc.stex", compress_mode, lossy, Image::COMPRESS_ETC, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel); r_platform_variants->push_back("etc"); formats_imported.push_back("etc"); } if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc")) { - _save_stex(image, p_save_path + ".pvrtc.stex", compress_mode, lossy, Image::COMPRESS_PVRTC4, mipmaps, stream, detect_3d, detect_roughness, force_rgbe, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel); + _save_stex(image, p_save_path + ".pvrtc.stex", compress_mode, lossy, Image::COMPRESS_PVRTC4, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel); r_platform_variants->push_back("pvrtc"); formats_imported.push_back("pvrtc"); } @@ -555,7 +566,7 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String } } else { //import normally - _save_stex(image, p_save_path + ".stex", compress_mode, lossy, Image::COMPRESS_S3TC /*this is ignored */, mipmaps, stream, detect_3d, detect_roughness, force_rgbe, detect_normal, force_normal, srgb_friendly_pack, false, mipmap_limit, normal_image, roughness_channel); + _save_stex(image, p_save_path + ".stex", compress_mode, lossy, Image::COMPRESS_S3TC /*this is ignored */, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, false, mipmap_limit, normal_image, roughness_channel); } if (r_metadata) { @@ -635,9 +646,9 @@ ResourceImporterTexture *ResourceImporterTexture::singleton = nullptr; ResourceImporterTexture::ResourceImporterTexture() { singleton = this; - StreamTexture::request_3d_callback = _texture_reimport_3d; - StreamTexture::request_roughness_callback = _texture_reimport_roughness; - StreamTexture::request_normal_callback = _texture_reimport_normal; + StreamTexture2D::request_3d_callback = _texture_reimport_3d; + StreamTexture2D::request_roughness_callback = _texture_reimport_roughness; + StreamTexture2D::request_normal_callback = _texture_reimport_normal; } ResourceImporterTexture::~ResourceImporterTexture() { diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h index e1c71ff1b8..da8ce3c0a8 100644 --- a/editor/import/resource_importer_texture.h +++ b/editor/import/resource_importer_texture.h @@ -37,7 +37,7 @@ #include "scene/resources/texture.h" #include "servers/rendering_server.h" -class StreamTexture; +class StreamTexture2D; class ResourceImporterTexture : public ResourceImporter { GDCLASS(ResourceImporterTexture, ResourceImporter); @@ -72,17 +72,17 @@ protected: Map<StringName, MakeInfo> make_flags; - static void _texture_reimport_roughness(const Ref<StreamTexture> &p_tex, const String &p_normal_path, RenderingServer::TextureDetectRoughnessChannel p_channel); - static void _texture_reimport_3d(const Ref<StreamTexture> &p_tex); - static void _texture_reimport_normal(const Ref<StreamTexture> &p_tex); + static void _texture_reimport_roughness(const Ref<StreamTexture2D> &p_tex, const String &p_normal_path, RenderingServer::TextureDetectRoughnessChannel p_channel); + static void _texture_reimport_3d(const Ref<StreamTexture2D> &p_tex); + static void _texture_reimport_normal(const Ref<StreamTexture2D> &p_tex); static ResourceImporterTexture *singleton; static const char *compression_formats[]; - void _save_stex(const Ref<Image> &p_image, const String &p_to_path, CompressMode p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, bool p_streamable, bool p_detect_3d, bool p_detect_srgb, bool p_force_rgbe, bool p_detect_normal, bool p_force_normal, bool p_srgb_friendly, bool p_force_po2_for_compressed, uint32_t p_limit_mipmap, const Ref<Image> &p_normal, Image::RoughnessChannel p_roughness_channel); + void _save_stex(const Ref<Image> &p_image, const String &p_to_path, CompressMode p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, bool p_streamable, bool p_detect_3d, bool p_detect_srgb, bool p_detect_normal, bool p_force_normal, bool p_srgb_friendly, bool p_force_po2_for_compressed, uint32_t p_limit_mipmap, const Ref<Image> &p_normal, Image::RoughnessChannel p_roughness_channel); public: - void save_to_stex_format(FileAccess *f, const Ref<Image> &p_image, CompressMode p_compress_mode, Image::UsedChannels p_channels, Image::CompressMode p_compress_format, float p_lossy_quality, bool p_force_rgbe); + static void save_to_stex_format(FileAccess *f, const Ref<Image> &p_image, CompressMode p_compress_mode, Image::UsedChannels p_channels, Image::CompressMode p_compress_format, float p_lossy_quality); static ResourceImporterTexture *get_singleton() { return singleton; } virtual String get_importer_name() const; diff --git a/editor/node_3d_editor_gizmos.cpp b/editor/node_3d_editor_gizmos.cpp index 901dfdfb38..cb0d9fa02b 100644 --- a/editor/node_3d_editor_gizmos.cpp +++ b/editor/node_3d_editor_gizmos.cpp @@ -41,6 +41,7 @@ #include "scene/3d/gi_probe.h" #include "scene/3d/gpu_particles_3d.h" #include "scene/3d/light_3d.h" +#include "scene/3d/lightmap_probe.h" #include "scene/3d/listener_3d.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/navigation_region_3d.h" @@ -3069,136 +3070,296 @@ void GIProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { } //// -#if 0 -BakedIndirectLightGizmoPlugin::BakedIndirectLightGizmoPlugin() { - Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/baked_indirect_light", Color(0.5, 0.6, 1)); - create_material("baked_indirect_light_material", gizmo_color); +BakedLightmapGizmoPlugin::BakedLightmapGizmoPlugin() { + Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/lightmap_lines", Color(0.5, 0.6, 1)); gizmo_color.a = 0.1; - create_material("baked_indirect_light_internal_material", gizmo_color); + create_material("lightmap_lines", gizmo_color); - create_icon_material("baked_indirect_light_icon", Node3DEditor::get_singleton()->get_icon("GizmoBakedLightmap", "EditorIcons")); - create_handle_material("handles"); -} + Ref<StandardMaterial3D> mat = memnew(StandardMaterial3D); + mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + mat->set_cull_mode(StandardMaterial3D::CULL_DISABLED); + mat->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + mat->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, false); -String BakedIndirectLightGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { + add_material("lightmap_probe_material", mat); - switch (p_idx) { - case 0: return "Extents X"; - case 1: return "Extents Y"; - case 2: return "Extents Z"; - } + create_icon_material("baked_indirect_light_icon", Node3DEditor::get_singleton()->get_theme_icon("GizmoBakedLightmap", "EditorIcons")); +} + +String BakedLightmapGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { return ""; } -Variant BakedIndirectLightGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { +Variant BakedLightmapGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { - BakedLightmap *baker = Object::cast_to<BakedLightmap>(p_gizmo->get_spatial_node()); - return baker->get_extents(); + return Variant(); +} +void BakedLightmapGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { } -void BakedIndirectLightGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) { +void BakedLightmapGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { +} + +bool BakedLightmapGizmoPlugin::has_gizmo(Node3D *p_spatial) { + return Object::cast_to<BakedLightmap>(p_spatial) != nullptr; +} + +String BakedLightmapGizmoPlugin::get_name() const { + return "BakedLightmap"; +} + +int BakedLightmapGizmoPlugin::get_priority() const { + return -1; +} + +void BakedLightmapGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { + + Ref<Material> icon = get_material("baked_indirect_light_icon", p_gizmo); BakedLightmap *baker = Object::cast_to<BakedLightmap>(p_gizmo->get_spatial_node()); + Ref<BakedLightmapData> data = baker->get_light_data(); - Transform gt = baker->get_global_transform(); - Transform gi = gt.affine_inverse(); + p_gizmo->add_unscaled_billboard(icon, 0.05); - Vector3 extents = baker->get_extents(); + if (data.is_null()) { + return; + } - Vector3 ray_from = p_camera->project_ray_origin(p_point); - Vector3 ray_dir = p_camera->project_ray_normal(p_point); + Ref<Material> material_lines = get_material("lightmap_lines", p_gizmo); + Ref<Material> material_probes = get_material("lightmap_probe_material", p_gizmo); - Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) }; + p_gizmo->clear(); - Vector3 axis; - axis[p_idx] = 1.0; + Vector<Vector3> lines; + Set<Vector2i> lines_found; - Vector3 ra, rb; - Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb); - float d = ra[p_idx]; - if (Node3DEditor::get_singleton()->is_snap_enabled()) { - d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap()); + Vector<Vector3> points = data->get_capture_points(); + if (points.size() == 0) { + return; + } + Vector<Color> sh = data->get_capture_sh(); + if (sh.size() != points.size() * 9) { + return; } - if (d < 0.001) - d = 0.001; + Vector<int> tetrahedrons = data->get_capture_tetrahedra(); - extents[p_idx] = d; - baker->set_extents(extents); -} + for (int i = 0; i < tetrahedrons.size(); i += 4) { -void BakedIndirectLightGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { + for (int j = 0; j < 4; j++) { + for (int k = j + 1; k < 4; k++) { - BakedLightmap *baker = Object::cast_to<BakedLightmap>(p_gizmo->get_spatial_node()); + Vector2i pair; + pair.x = tetrahedrons[i + j]; + pair.y = tetrahedrons[i + k]; - Vector3 restore = p_restore; + if (pair.y < pair.x) { + SWAP(pair.x, pair.y); + } + if (lines_found.has(pair)) { + continue; + } + lines_found.insert(pair); + lines.push_back(points[pair.x]); + lines.push_back(points[pair.y]); + } + } + } - if (p_cancel) { - baker->set_extents(restore); - return; + p_gizmo->add_lines(lines, material_lines); + + int stack_count = 8; + int sector_count = 16; + + float sector_step = 2 * Math_PI / sector_count; + float stack_step = Math_PI / stack_count; + + Vector<Vector3> vertices; + Vector<Color> colors; + Vector<int> indices; + float radius = 0.3; + + for (int p = 0; p < points.size(); p++) { + + int vertex_base = vertices.size(); + Vector3 sh_col[9]; + for (int i = 0; i < 9; i++) { + sh_col[i].x = sh[p * 9 + i].r; + sh_col[i].y = sh[p * 9 + i].g; + sh_col[i].z = sh[p * 9 + i].b; + } + + for (int i = 0; i <= stack_count; ++i) { + float stack_angle = Math_PI / 2 - i * stack_step; // starting from pi/2 to -pi/2 + float xy = radius * Math::cos(stack_angle); // r * cos(u) + float z = radius * Math::sin(stack_angle); // r * sin(u) + + // add (sector_count+1) vertices per stack + // the first and last vertices have same position and normal, but different tex coords + for (int j = 0; j <= sector_count; ++j) { + float sector_angle = j * sector_step; // starting from 0 to 2pi + + // vertex position (x, y, z) + float x = xy * Math::cos(sector_angle); // r * cos(u) * cos(v) + float y = xy * Math::sin(sector_angle); // r * cos(u) * sin(v) + + Vector3 n = Vector3(x, z, y); + vertices.push_back(points[p] + n); + n.normalize(); + + const float c1 = 0.429043; + const float c2 = 0.511664; + const float c3 = 0.743125; + const float c4 = 0.886227; + const float c5 = 0.247708; + Vector3 light = (c1 * sh_col[8] * (n.x * n.x - n.y * n.y) + + c3 * sh_col[6] * n.z * n.z + + c4 * sh_col[0] - + c5 * sh_col[6] + + 2.0 * c1 * sh_col[4] * n.x * n.y + + 2.0 * c1 * sh_col[7] * n.x * n.z + + 2.0 * c1 * sh_col[5] * n.y * n.z + + 2.0 * c2 * sh_col[3] * n.x + + 2.0 * c2 * sh_col[1] * n.y + + 2.0 * c2 * sh_col[2] * n.z); + + colors.push_back(Color(light.x, light.y, light.z, 1)); + } + } + + for (int i = 0; i < stack_count; ++i) { + int k1 = i * (sector_count + 1); // beginning of current stack + int k2 = k1 + sector_count + 1; // beginning of next stack + + for (int j = 0; j < sector_count; ++j, ++k1, ++k2) { + // 2 triangles per sector excluding first and last stacks + // k1 => k2 => k1+1 + if (i != 0) { + indices.push_back(vertex_base + k1); + indices.push_back(vertex_base + k2); + indices.push_back(vertex_base + k1 + 1); + } + + // k1+1 => k2 => k2+1 + if (i != (stack_count - 1)) { + indices.push_back(vertex_base + k1 + 1); + indices.push_back(vertex_base + k2); + indices.push_back(vertex_base + k2 + 1); + } + } + } } - UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo(); - ur->create_action(TTR("Change Probe Extents")); - ur->add_do_method(baker, "set_extents", baker->get_extents()); - ur->add_undo_method(baker, "set_extents", restore); - ur->commit_action(); + Array array; + array.resize(RS::ARRAY_MAX); + array[RS::ARRAY_VERTEX] = vertices; + array[RS::ARRAY_INDEX] = indices; + array[RS::ARRAY_COLOR] = colors; + + Ref<ArrayMesh> mesh; + mesh.instance(); + mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, array, Array(), Dictionary(), 0); //no compression + mesh->surface_set_material(0, material_probes); + + p_gizmo->add_mesh(mesh); } +///////// -bool BakedIndirectLightGizmoPlugin::has_gizmo(Spatial *p_spatial) { - return Object::cast_to<BakedLightmap>(p_spatial) != nullptr; +LightmapProbeGizmoPlugin::LightmapProbeGizmoPlugin() { + Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/lightprobe_lines", Color(0.5, 0.6, 1)); + + gizmo_color.a = 0.3; + create_material("lightprobe_lines", gizmo_color); } -String BakedIndirectLightGizmoPlugin::get_name() const { - return "BakedLightmap"; +String LightmapProbeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { + + return ""; } +Variant LightmapProbeGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { -int BakedIndirectLightGizmoPlugin::get_priority() const { - return -1; + return Variant(); +} +void LightmapProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { } -void BakedIndirectLightGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { +void LightmapProbeGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { +} - BakedLightmap *baker = Object::cast_to<BakedLightmap>(p_gizmo->get_spatial_node()); +bool LightmapProbeGizmoPlugin::has_gizmo(Node3D *p_spatial) { + return Object::cast_to<LightmapProbe>(p_spatial) != nullptr; +} - Ref<Material> material = get_material("baked_indirect_light_material", p_gizmo); - Ref<Material> icon = get_material("baked_indirect_light_icon", p_gizmo); - Ref<Material> material_internal = get_material("baked_indirect_light_internal_material", p_gizmo); +String LightmapProbeGizmoPlugin::get_name() const { + return "LightmapProbe"; +} + +int LightmapProbeGizmoPlugin::get_priority() const { + return -1; +} + +void LightmapProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { + + Ref<Material> material_lines = get_material("lightprobe_lines", p_gizmo); p_gizmo->clear(); Vector<Vector3> lines; - Vector3 extents = baker->get_extents(); - AABB aabb = AABB(-extents, extents * 2); + int stack_count = 8; + int sector_count = 16; - for (int i = 0; i < 12; i++) { - Vector3 a, b; - aabb.get_edge(i, a, b); - lines.push_back(a); - lines.push_back(b); - } + float sector_step = 2 * Math_PI / sector_count; + float stack_step = Math_PI / stack_count; - p_gizmo->add_lines(lines, material); + Vector<Vector3> vertices; + float radius = 0.2; - Vector<Vector3> handles; + for (int i = 0; i <= stack_count; ++i) { + float stack_angle = Math_PI / 2 - i * stack_step; // starting from pi/2 to -pi/2 + float xy = radius * Math::cos(stack_angle); // r * cos(u) + float z = radius * Math::sin(stack_angle); // r * sin(u) - for (int i = 0; i < 3; i++) { + // add (sector_count+1) vertices per stack + // the first and last vertices have same position and normal, but different tex coords + for (int j = 0; j <= sector_count; ++j) { + float sector_angle = j * sector_step; // starting from 0 to 2pi - Vector3 ax; - ax[i] = aabb.position[i] + aabb.size[i]; - handles.push_back(ax); + // vertex position (x, y, z) + float x = xy * Math::cos(sector_angle); // r * cos(u) * cos(v) + float y = xy * Math::sin(sector_angle); // r * cos(u) * sin(v) + + Vector3 n = Vector3(x, z, y); + vertices.push_back(n); + } } - if (p_gizmo->is_selected()) { - p_gizmo->add_solid_box(material_internal, aabb.get_size()); + for (int i = 0; i < stack_count; ++i) { + int k1 = i * (sector_count + 1); // beginning of current stack + int k2 = k1 + sector_count + 1; // beginning of next stack + + for (int j = 0; j < sector_count; ++j, ++k1, ++k2) { + // 2 triangles per sector excluding first and last stacks + // k1 => k2 => k1+1 + if (i != 0) { + lines.push_back(vertices[k1]); + lines.push_back(vertices[k2]); + lines.push_back(vertices[k1]); + lines.push_back(vertices[k1 + 1]); + } + + if (i != (stack_count - 1)) { + lines.push_back(vertices[k1 + 1]); + lines.push_back(vertices[k2]); + lines.push_back(vertices[k2]); + lines.push_back(vertices[k2 + 1]); + } + } } - p_gizmo->add_unscaled_billboard(icon, 0.05); - p_gizmo->add_handles(handles, get_material("handles")); + p_gizmo->add_lines(lines, material_lines); } -#endif //// CollisionShape3DGizmoPlugin::CollisionShape3DGizmoPlugin() { @@ -3753,10 +3914,10 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Vector3 n2 = p.normal.cross(n1).normalized(); Vector3 pface[4] = { - p.normal * p.distance + n1 * 10.0 + n2 * 10.0, - p.normal * p.distance + n1 * 10.0 + n2 * -10.0, - p.normal * p.distance + n1 * -10.0 + n2 * -10.0, - p.normal * p.distance + n1 * -10.0 + n2 * 10.0, + p.normal * p.d + n1 * 10.0 + n2 * 10.0, + p.normal * p.d + n1 * 10.0 + n2 * -10.0, + p.normal * p.d + n1 * -10.0 + n2 * -10.0, + p.normal * p.d + n1 * -10.0 + n2 * 10.0, }; points.push_back(pface[0]); @@ -3767,8 +3928,8 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { points.push_back(pface[3]); points.push_back(pface[3]); points.push_back(pface[0]); - points.push_back(p.normal * p.distance); - points.push_back(p.normal * p.distance + p.normal * 3); + points.push_back(p.normal * p.d); + points.push_back(p.normal * p.d + p.normal * 3); p_gizmo->add_lines(points, material); p_gizmo->add_collision_segments(points); diff --git a/editor/node_3d_editor_gizmos.h b/editor/node_3d_editor_gizmos.h index 6432feeecb..c25fff528c 100644 --- a/editor/node_3d_editor_gizmos.h +++ b/editor/node_3d_editor_gizmos.h @@ -321,25 +321,42 @@ public: GIProbeGizmoPlugin(); }; -#if 0 -class BakedIndirectLightGizmoPlugin : public EditorNode3DGizmoPlugin { +class BakedLightmapGizmoPlugin : public EditorNode3DGizmoPlugin { - GDCLASS(BakedIndirectLightGizmoPlugin, EditorNode3DGizmoPlugin); + GDCLASS(BakedLightmapGizmoPlugin, EditorNode3DGizmoPlugin); public: - bool has_gizmo(Spatial *p_spatial); + bool has_gizmo(Node3D *p_spatial); + String get_name() const; + int get_priority() const; + void redraw(EditorNode3DGizmo *p_gizmo); + + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const; + Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const; + void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point); + void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false); + + BakedLightmapGizmoPlugin(); +}; + +class LightmapProbeGizmoPlugin : public EditorNode3DGizmoPlugin { + + GDCLASS(LightmapProbeGizmoPlugin, EditorNode3DGizmoPlugin); + +public: + bool has_gizmo(Node3D *p_spatial); String get_name() const; int get_priority() const; void redraw(EditorNode3DGizmo *p_gizmo); String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const; Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const; - void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point); + void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point); void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false); - BakedIndirectLightGizmoPlugin(); + LightmapProbeGizmoPlugin(); }; -#endif + class CollisionShape3DGizmoPlugin : public EditorNode3DGizmoPlugin { GDCLASS(CollisionShape3DGizmoPlugin, EditorNode3DGizmoPlugin); diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp index 17cb68df3a..4ea84e716b 100644 --- a/editor/plugins/animation_blend_space_2d_editor.cpp +++ b/editor/plugins/animation_blend_space_2d_editor.cpp @@ -32,7 +32,7 @@ #include "core/input/input.h" #include "core/io/resource_loader.h" -#include "core/math/delaunay.h" +#include "core/math/delaunay_2d.h" #include "core/os/keyboard.h" #include "core/project_settings.h" #include "editor/editor_scale.h" diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index ed51a2d2cf..509bf59716 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -32,7 +32,7 @@ #include "core/input/input.h" #include "core/io/resource_loader.h" -#include "core/math/delaunay.h" +#include "core/math/delaunay_2d.h" #include "core/os/keyboard.h" #include "core/project_settings.h" #include "editor/editor_scale.h" diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp index 9452c0f11b..9c48444e3e 100644 --- a/editor/plugins/animation_tree_editor_plugin.cpp +++ b/editor/plugins/animation_tree_editor_plugin.cpp @@ -36,7 +36,7 @@ #include "animation_state_machine_editor.h" #include "core/input/input.h" #include "core/io/resource_loader.h" -#include "core/math/delaunay.h" +#include "core/math/delaunay_2d.h" #include "core/os/keyboard.h" #include "core/project_settings.h" #include "editor/editor_scale.h" diff --git a/editor/plugins/baked_lightmap_editor_plugin.cpp b/editor/plugins/baked_lightmap_editor_plugin.cpp index ba161244d6..f754dd4725 100644 --- a/editor/plugins/baked_lightmap_editor_plugin.cpp +++ b/editor/plugins/baked_lightmap_editor_plugin.cpp @@ -28,23 +28,36 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#if 0 #include "baked_lightmap_editor_plugin.h" -void BakedLightmapEditorPlugin::_bake() { +void BakedLightmapEditorPlugin::_bake_select_file(const String &p_file) { if (lightmap) { BakedLightmap::BakeError err; if (get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root() == lightmap) { - err = lightmap->bake(lightmap); + err = lightmap->bake(lightmap, p_file, bake_func_step); } else { - err = lightmap->bake(lightmap->get_parent()); + err = lightmap->bake(lightmap->get_parent(), p_file, bake_func_step); } + bake_func_end(); + switch (err) { - case BakedLightmap::BAKE_ERROR_NO_SAVE_PATH: - EditorNode::get_singleton()->show_warning(TTR("Can't determine a save path for lightmap images.\nSave your scene (for images to be saved in the same dir), or pick a save path from the BakedLightmap properties.")); - break; + case BakedLightmap::BAKE_ERROR_NO_SAVE_PATH: { + String scene_path = lightmap->get_filename(); + if (scene_path == String()) { + scene_path = lightmap->get_owner()->get_filename(); + } + if (scene_path == String()) { + EditorNode::get_singleton()->show_warning(TTR("Can't determine a save path for lightmap images.\nSave your scene and try again.")); + break; + } + scene_path = scene_path.get_basename() + ".lmbake"; + + file_dialog->set_current_path(scene_path); + file_dialog->popup_centered_ratio(); + + } break; case BakedLightmap::BAKE_ERROR_NO_MESHES: EditorNode::get_singleton()->show_warning(TTR("No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake Light' flag is on.")); break; @@ -57,6 +70,11 @@ void BakedLightmapEditorPlugin::_bake() { } } +void BakedLightmapEditorPlugin::_bake() { + + _bake_select_file(""); +} + void BakedLightmapEditorPlugin::edit(Object *p_object) { BakedLightmap *s = Object::cast_to<BakedLightmap>(p_object); @@ -83,23 +101,20 @@ void BakedLightmapEditorPlugin::make_visible(bool p_visible) { EditorProgress *BakedLightmapEditorPlugin::tmp_progress = nullptr; -void BakedLightmapEditorPlugin::bake_func_begin(int p_steps) { +bool BakedLightmapEditorPlugin::bake_func_step(float p_progress, const String &p_description, void *, bool p_refresh) { - ERR_FAIL_COND(tmp_progress != nullptr); - - tmp_progress = memnew(EditorProgress("bake_lightmaps", TTR("Bake Lightmaps"), p_steps, true)); -} - -bool BakedLightmapEditorPlugin::bake_func_step(int p_step, const String &p_description) { - - ERR_FAIL_COND_V(tmp_progress == nullptr, false); - return tmp_progress->step(p_description, p_step, false); + if (!tmp_progress) { + tmp_progress = memnew(EditorProgress("bake_lightmaps", TTR("Bake Lightmaps"), 1000, false)); + ERR_FAIL_COND_V(tmp_progress == nullptr, false); + } + return tmp_progress->step(p_description, p_progress * 1000, p_refresh); } void BakedLightmapEditorPlugin::bake_func_end() { - ERR_FAIL_COND(tmp_progress == nullptr); - memdelete(tmp_progress); - tmp_progress = nullptr; + if (tmp_progress != nullptr) { + memdelete(tmp_progress); + tmp_progress = nullptr; + } } void BakedLightmapEditorPlugin::_bind_methods() { @@ -111,18 +126,20 @@ BakedLightmapEditorPlugin::BakedLightmapEditorPlugin(EditorNode *p_node) { editor = p_node; bake = memnew(ToolButton); - bake->set_icon(editor->get_gui_base()->get_icon("Bake", "EditorIcons")); + bake->set_icon(editor->get_gui_base()->get_theme_icon("Bake", "EditorIcons")); bake->set_text(TTR("Bake Lightmaps")); bake->hide(); - bake->connect("pressed", this, "_bake"); + bake->connect("pressed", Callable(this, "_bake")); add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, bake); lightmap = nullptr; - BakedLightmap::bake_begin_function = bake_func_begin; - BakedLightmap::bake_step_function = bake_func_step; - BakedLightmap::bake_end_function = bake_func_end; + file_dialog = memnew(EditorFileDialog); + file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); + file_dialog->add_filter("*.lmbake ; LightMap Bake"); + file_dialog->set_title(TTR("Select lightmap bake file:")); + file_dialog->connect("file_selected", callable_mp(this, &BakedLightmapEditorPlugin::_bake_select_file)); + bake->add_child(file_dialog); } BakedLightmapEditorPlugin::~BakedLightmapEditorPlugin() { } -#endif diff --git a/editor/plugins/baked_lightmap_editor_plugin.h b/editor/plugins/baked_lightmap_editor_plugin.h index 818cdfe8fa..2dbc09fc1d 100644 --- a/editor/plugins/baked_lightmap_editor_plugin.h +++ b/editor/plugins/baked_lightmap_editor_plugin.h @@ -28,7 +28,6 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#if 0 #ifndef BAKED_LIGHTMAP_EDITOR_PLUGIN_H #define BAKED_LIGHTMAP_EDITOR_PLUGIN_H @@ -46,11 +45,12 @@ class BakedLightmapEditorPlugin : public EditorPlugin { ToolButton *bake; EditorNode *editor; + EditorFileDialog *file_dialog; static EditorProgress *tmp_progress; - static void bake_func_begin(int p_steps); - static bool bake_func_step(int p_step, const String &p_description); + static bool bake_func_step(float p_progress, const String &p_description, void *, bool p_refresh); static void bake_func_end(); + void _bake_select_file(const String &p_file); void _bake(); protected: @@ -67,5 +67,4 @@ public: ~BakedLightmapEditorPlugin(); }; -#endif // BAKED_LIGHTMAP_EDITOR_PLUGIN_H #endif diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 65c0763e63..b5fcf82d76 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -6161,7 +6161,7 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian type == "ViewportTexture" || type == "CurveTexture" || type == "GradientTexture" || - type == "StreamTexture" || + type == "StreamTexture2D" || type == "AtlasTexture" || type == "LargeTexture") { Ref<Texture2D> texture = Ref<Texture2D>(Object::cast_to<Texture2D>(*res)); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index bac00ed038..69f8efa86e 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -682,11 +682,11 @@ void Node3DEditorViewport::_select_region() { } Plane near(cam_pos, -_get_camera_normal()); - near.distance -= get_znear(); + near.d -= get_znear(); frustum.push_back(near); Plane far = -near; - far.distance += get_zfar(); + far.d += get_zfar(); frustum.push_back(far); Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_convex(frustum, get_tree()->get_root()->get_world_3d()->get_scenario()); @@ -6008,7 +6008,8 @@ void Node3DEditor::_register_all_gizmos() { add_gizmo_plugin(Ref<ReflectionProbeGizmoPlugin>(memnew(ReflectionProbeGizmoPlugin))); add_gizmo_plugin(Ref<DecalGizmoPlugin>(memnew(DecalGizmoPlugin))); add_gizmo_plugin(Ref<GIProbeGizmoPlugin>(memnew(GIProbeGizmoPlugin))); - // add_gizmo_plugin(Ref<BakedIndirectLightGizmoPlugin>(memnew(BakedIndirectLightGizmoPlugin))); + add_gizmo_plugin(Ref<BakedLightmapGizmoPlugin>(memnew(BakedLightmapGizmoPlugin))); + add_gizmo_plugin(Ref<LightmapProbeGizmoPlugin>(memnew(LightmapProbeGizmoPlugin))); add_gizmo_plugin(Ref<CollisionShape3DGizmoPlugin>(memnew(CollisionShape3DGizmoPlugin))); add_gizmo_plugin(Ref<CollisionPolygon3DGizmoPlugin>(memnew(CollisionPolygon3DGizmoPlugin))); add_gizmo_plugin(Ref<NavigationRegion3DGizmoPlugin>(memnew(NavigationRegion3DGizmoPlugin))); diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp index c1184c1c89..7a3e571f16 100644 --- a/editor/plugins/texture_editor_plugin.cpp +++ b/editor/plugins/texture_editor_plugin.cpp @@ -84,8 +84,8 @@ void TextureEditor::_notification(int p_what) { String format; if (Object::cast_to<ImageTexture>(*texture)) { format = Image::get_format_name(Object::cast_to<ImageTexture>(*texture)->get_format()); - } else if (Object::cast_to<StreamTexture>(*texture)) { - format = Image::get_format_name(Object::cast_to<StreamTexture>(*texture)->get_format()); + } else if (Object::cast_to<StreamTexture2D>(*texture)) { + format = Image::get_format_name(Object::cast_to<StreamTexture2D>(*texture)->get_format()); } else { format = texture->get_class(); } @@ -144,7 +144,7 @@ TextureEditor::~TextureEditor() { // bool EditorInspectorPluginTexture::can_handle(Object *p_object) { - return Object::cast_to<ImageTexture>(p_object) != nullptr || Object::cast_to<AtlasTexture>(p_object) != nullptr || Object::cast_to<StreamTexture>(p_object) != nullptr || Object::cast_to<LargeTexture>(p_object) != nullptr || Object::cast_to<AnimatedTexture>(p_object) != nullptr; + return Object::cast_to<ImageTexture>(p_object) != nullptr || Object::cast_to<AtlasTexture>(p_object) != nullptr || Object::cast_to<StreamTexture2D>(p_object) != nullptr || Object::cast_to<LargeTexture>(p_object) != nullptr || Object::cast_to<AnimatedTexture>(p_object) != nullptr; } void EditorInspectorPluginTexture::parse_begin(Object *p_object) { diff --git a/editor/plugins/texture_layered_editor_plugin.cpp b/editor/plugins/texture_layered_editor_plugin.cpp new file mode 100644 index 0000000000..6d716951b3 --- /dev/null +++ b/editor/plugins/texture_layered_editor_plugin.cpp @@ -0,0 +1,286 @@ +/*************************************************************************/ +/* texture_editor_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "texture_layered_editor_plugin.h" + +#include "core/io/resource_loader.h" +#include "core/project_settings.h" +#include "editor/editor_settings.h" + +void TextureLayeredEditor::_gui_input(Ref<InputEvent> p_event) { + Ref<InputEventMouseMotion> mm = p_event; + if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) { + y_rot += -mm->get_relative().x * 0.01; + x_rot += mm->get_relative().y * 0.01; + _update_material(); + } +} + +void TextureLayeredEditor::_texture_rect_draw() { + texture_rect->draw_rect(Rect2(Point2(), texture_rect->get_size()), Color(1, 1, 1, 1)); +} + +void TextureLayeredEditor::_notification(int p_what) { + + if (p_what == NOTIFICATION_READY) { + + //get_scene()->connect("node_removed",this,"_node_removed"); + } + if (p_what == NOTIFICATION_RESIZED) { + _texture_rect_update_area(); + } + + if (p_what == NOTIFICATION_DRAW) { + + Ref<Texture2D> checkerboard = get_theme_icon("Checkerboard", "EditorIcons"); + Size2 size = get_size(); + + draw_texture_rect(checkerboard, Rect2(Point2(), size), true); + } +} + +void TextureLayeredEditor::_changed_callback(Object *p_changed, const char *p_prop) { + + if (!is_visible()) + return; + update(); +} + +void TextureLayeredEditor::_update_material() { + + materials[0]->set_shader_param("layer", layer->get_value()); + materials[2]->set_shader_param("layer", layer->get_value()); + materials[texture->get_layered_type()]->set_shader_param("tex", texture->get_rid()); + + Vector3 v(1, 1, 1); + v.normalize(); + + Basis b; + b.rotate(Vector3(1, 0, 0), x_rot); + b.rotate(Vector3(0, 1, 0), y_rot); + + materials[1]->set_shader_param("normal", v); + materials[1]->set_shader_param("rot", b); + materials[2]->set_shader_param("normal", v); + materials[2]->set_shader_param("rot", b); + + String format = Image::get_format_name(texture->get_format()); + + String text; + if (texture->get_layered_type() == TextureLayered::LAYERED_TYPE_2D_ARRAY) { + text = itos(texture->get_width()) + "x" + itos(texture->get_height()) + " (x " + itos(texture->get_layers()) + ")" + format; + } else if (texture->get_layered_type() == TextureLayered::LAYERED_TYPE_CUBEMAP) { + text = itos(texture->get_width()) + "x" + itos(texture->get_height()) + " " + format; + } else if (texture->get_layered_type() == TextureLayered::LAYERED_TYPE_CUBEMAP_ARRAY) { + text = itos(texture->get_width()) + "x" + itos(texture->get_height()) + " (x " + itos(texture->get_layers() / 6) + ")" + format; + } + + info->set_text(text); +} + +void TextureLayeredEditor::_make_shaders() { + String shader_2d_array = "" + "shader_type canvas_item;\n" + "uniform sampler2DArray tex;\n" + "uniform float layer;\n" + "void fragment() {\n" + " COLOR = textureLod(tex,vec3(UV,layer),0.0);\n" + "}"; + + shaders[0].instance(); + shaders[0]->set_code(shader_2d_array); + + String shader_cube = "" + "shader_type canvas_item;\n" + "uniform samplerCube tex;\n" + "uniform vec3 normal;\n" + "uniform mat3 rot;\n" + "void fragment() {\n" + " vec3 n = rot * normalize(vec3(normal.xy*(UV * 2.0 - 1.0),normal.z));\n" + " COLOR = textureLod(tex,n,0.0);\n" + "}"; + + shaders[1].instance(); + shaders[1]->set_code(shader_cube); + + String shader_cube_array = "" + "shader_type canvas_item;\n" + "uniform samplerCubeArray tex;\n" + "uniform vec3 normal;\n" + "uniform mat3 rot;\n" + "uniform float layer;\n" + "void fragment() {\n" + " vec3 n = rot * normalize(vec3(normal.xy*(UV * 2.0 - 1.0),normal.z));\n" + " COLOR = textureLod(tex,vec4(n,layer),0.0);\n" + "}"; + + shaders[2].instance(); + shaders[2]->set_code(shader_cube_array); + + for (int i = 0; i < 3; i++) { + materials[i].instance(); + materials[i]->set_shader(shaders[i]); + } +} + +void TextureLayeredEditor::_texture_rect_update_area() { + + Size2 size = get_size(); + int tex_width = texture->get_width() * size.height / texture->get_height(); + int tex_height = size.height; + + if (tex_width > size.width) { + tex_width = size.width; + tex_height = texture->get_height() * tex_width / texture->get_width(); + } + + // Prevent the texture from being unpreviewable after the rescale, so that we can still see something + if (tex_height <= 0) + tex_height = 1; + if (tex_width <= 0) + tex_width = 1; + + int ofs_x = (size.width - tex_width) / 2; + int ofs_y = (size.height - tex_height) / 2; + + texture_rect->set_position(Vector2(ofs_x, ofs_y)); + texture_rect->set_size(Vector2(tex_width, tex_height)); +} + +void TextureLayeredEditor::edit(Ref<TextureLayered> p_texture) { + + if (!texture.is_null()) + texture->remove_change_receptor(this); + + texture = p_texture; + + if (!texture.is_null()) { + + if (shaders[0].is_null()) { + _make_shaders(); + } + + texture->add_change_receptor(this); + update(); + texture_rect->set_material(materials[texture->get_layered_type()]); + setting = true; + if (texture->get_layered_type() == TextureLayered::LAYERED_TYPE_2D_ARRAY) { + layer->set_max(texture->get_layers() - 1); + layer->set_value(0); + layer->show(); + } else if (texture->get_layered_type() == TextureLayered::LAYERED_TYPE_CUBEMAP_ARRAY) { + layer->set_max(texture->get_layers() / 6 - 1); + layer->set_value(0); + layer->show(); + } else { + layer->hide(); + } + x_rot = 0; + y_rot = 0; + _update_material(); + setting = false; + _texture_rect_update_area(); + } else { + hide(); + } +} + +void TextureLayeredEditor::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_gui_input"), &TextureLayeredEditor::_gui_input); + ClassDB::bind_method(D_METHOD("_layer_changed"), &TextureLayeredEditor::_layer_changed); +} + +TextureLayeredEditor::TextureLayeredEditor() { + + set_texture_repeat(TextureRepeat::TEXTURE_REPEAT_ENABLED); + set_custom_minimum_size(Size2(1, 150)); + texture_rect = memnew(Control); + texture_rect->connect("draw", callable_mp(this, &TextureLayeredEditor::_texture_rect_draw)); + texture_rect->set_mouse_filter(MOUSE_FILTER_IGNORE); + add_child(texture_rect); + + layer = memnew(SpinBox); + layer->set_step(1); + layer->set_max(100); + add_child(layer); + layer->set_anchor(MARGIN_RIGHT, 1); + layer->set_anchor(MARGIN_LEFT, 1); + layer->set_h_grow_direction(GROW_DIRECTION_BEGIN); + layer->set_modulate(Color(1, 1, 1, 0.8)); + info = memnew(Label); + add_child(info); + info->set_anchor(MARGIN_RIGHT, 1); + info->set_anchor(MARGIN_LEFT, 1); + info->set_anchor(MARGIN_BOTTOM, 1); + info->set_anchor(MARGIN_TOP, 1); + info->set_h_grow_direction(GROW_DIRECTION_BEGIN); + info->set_v_grow_direction(GROW_DIRECTION_BEGIN); + info->add_theme_color_override("font_color", Color(1, 1, 1, 1)); + info->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 0.5)); + info->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 0.5)); + info->add_theme_constant_override("shadow_as_outline", 1); + info->add_theme_constant_override("shadow_offset_x", 2); + info->add_theme_constant_override("shadow_offset_y", 2); + + setting = false; + layer->connect("value_changed", Callable(this, "_layer_changed")); +} + +TextureLayeredEditor::~TextureLayeredEditor() { + if (!texture.is_null()) { + texture->remove_change_receptor(this); + } +} +// +bool EditorInspectorPluginLayeredTexture::can_handle(Object *p_object) { + + return Object::cast_to<TextureLayered>(p_object) != nullptr; +} + +void EditorInspectorPluginLayeredTexture::parse_begin(Object *p_object) { + + TextureLayered *texture = Object::cast_to<TextureLayered>(p_object); + if (!texture) { + return; + } + Ref<TextureLayered> m(texture); + + TextureLayeredEditor *editor = memnew(TextureLayeredEditor); + editor->edit(m); + add_custom_control(editor); +} + +TextureLayeredEditorPlugin::TextureLayeredEditorPlugin(EditorNode *p_node) { + + Ref<EditorInspectorPluginLayeredTexture> plugin; + plugin.instance(); + add_inspector_plugin(plugin); +} diff --git a/editor/plugins/texture_layered_editor_plugin.h b/editor/plugins/texture_layered_editor_plugin.h new file mode 100644 index 0000000000..e8503e845e --- /dev/null +++ b/editor/plugins/texture_layered_editor_plugin.h @@ -0,0 +1,95 @@ +/*************************************************************************/ +/* texture_editor_plugin.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEXTURE_LAYERED_EDITOR_PLUGIN_H +#define TEXTURE_LAYERED_EDITOR_PLUGIN_H + +#include "editor/editor_node.h" +#include "editor/editor_plugin.h" +#include "scene/resources/shader.h" +#include "scene/resources/texture.h" +class TextureLayeredEditor : public Control { + + GDCLASS(TextureLayeredEditor, Control); + + SpinBox *layer; + Label *info; + Ref<TextureLayered> texture; + + Ref<Shader> shaders[3]; + Ref<ShaderMaterial> materials[3]; + + float x_rot = 0; + float y_rot = 0; + Control *texture_rect; + + void _make_shaders(); + + void _update_material(); + bool setting; + void _layer_changed(double) { + if (!setting) + _update_material(); + } + + void _texture_rect_update_area(); + void _texture_rect_draw(); + +protected: + void _notification(int p_what); + void _gui_input(Ref<InputEvent> p_event); + void _changed_callback(Object *p_changed, const char *p_prop); + static void _bind_methods(); + +public: + void edit(Ref<TextureLayered> p_texture); + TextureLayeredEditor(); + ~TextureLayeredEditor(); +}; + +class EditorInspectorPluginLayeredTexture : public EditorInspectorPlugin { + GDCLASS(EditorInspectorPluginLayeredTexture, EditorInspectorPlugin); + +public: + virtual bool can_handle(Object *p_object); + virtual void parse_begin(Object *p_object); +}; + +class TextureLayeredEditorPlugin : public EditorPlugin { + + GDCLASS(TextureLayeredEditorPlugin, EditorPlugin); + +public: + virtual String get_name() const { return "TextureLayered"; } + + TextureLayeredEditorPlugin(EditorNode *p_node); +}; + +#endif // TEXTURE_EDITOR_PLUGIN_H diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index 15fbf19fdb..60329fb7bc 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -752,7 +752,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: value_editor[0]->set_text(String::num(plane.normal.x)); value_editor[1]->set_text(String::num(plane.normal.y)); value_editor[2]->set_text(String::num(plane.normal.z)); - value_editor[3]->set_text(String::num(plane.distance)); + value_editor[3]->set_text(String::num(plane.d)); } break; case Variant::QUAT: { @@ -1598,7 +1598,7 @@ void CustomPropertyEditor::_modified(String p_string) { pl.normal.x = _parse_real_expression(value_editor[0]->get_text()); pl.normal.y = _parse_real_expression(value_editor[1]->get_text()); pl.normal.z = _parse_real_expression(value_editor[2]->get_text()); - pl.distance = _parse_real_expression(value_editor[3]->get_text()); + pl.d = _parse_real_expression(value_editor[3]->get_text()); v = pl; _emit_changed_whole_or_field(); diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 5ee5fbcf9c..6e00e3c291 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -97,8 +97,8 @@ void SceneTreeDock::_unhandled_key_input(Ref<InputEvent> p_event) { _tool_selected(TOOL_DUPLICATE); } else if (ED_IS_SHORTCUT("scene_tree/attach_script", p_event)) { _tool_selected(TOOL_ATTACH_SCRIPT); - } else if (ED_IS_SHORTCUT("scene_tree/clear_script", p_event)) { - _tool_selected(TOOL_CLEAR_SCRIPT); + } else if (ED_IS_SHORTCUT("scene_tree/detach_script", p_event)) { + _tool_selected(TOOL_DETACH_SCRIPT); } else if (ED_IS_SHORTCUT("scene_tree/move_up", p_event)) { _tool_selected(TOOL_MOVE_UP); } else if (ED_IS_SHORTCUT("scene_tree/move_down", p_event)) { @@ -426,7 +426,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { case TOOL_ATTACH_SCRIPT: { attach_script_to_selected(false); } break; - case TOOL_CLEAR_SCRIPT: { + case TOOL_DETACH_SCRIPT: { if (!profile_allow_script_editing) { break; @@ -437,7 +437,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { if (selection.empty()) return; - editor_data->get_undo_redo().create_action(TTR("Clear Script")); + editor_data->get_undo_redo().create_action(TTR("Detach Script")); editor_data->get_undo_redo().add_do_method(editor, "push_item", (Script *)nullptr); for (int i = 0; i < selection.size(); i++) { @@ -1071,7 +1071,7 @@ void SceneTreeDock::_notification(int p_what) { button_add->set_icon(get_theme_icon("Add", "EditorIcons")); button_instance->set_icon(get_theme_icon("Instance", "EditorIcons")); button_create_script->set_icon(get_theme_icon("ScriptCreate", "EditorIcons")); - button_clear_script->set_icon(get_theme_icon("ScriptRemove", "EditorIcons")); + button_detach_script->set_icon(get_theme_icon("ScriptRemove", "EditorIcons")); filter->set_right_icon(get_theme_icon("Search", "EditorIcons")); filter->set_clear_button_enabled(true); @@ -1148,7 +1148,7 @@ void SceneTreeDock::_notification(int p_what) { button_add->set_icon(get_theme_icon("Add", "EditorIcons")); button_instance->set_icon(get_theme_icon("Instance", "EditorIcons")); button_create_script->set_icon(get_theme_icon("ScriptCreate", "EditorIcons")); - button_clear_script->set_icon(get_theme_icon("ScriptRemove", "EditorIcons")); + button_detach_script->set_icon(get_theme_icon("ScriptRemove", "EditorIcons")); filter->set_right_icon(get_theme_icon("Search", "EditorIcons")); filter->set_clear_button_enabled(true); @@ -1883,18 +1883,18 @@ void SceneTreeDock::_update_script_button() { if (!profile_allow_script_editing) { button_create_script->hide(); - button_clear_script->hide(); + button_detach_script->hide(); } else if (EditorNode::get_singleton()->get_editor_selection()->get_selection().size() == 0) { button_create_script->hide(); - button_clear_script->hide(); + button_detach_script->hide(); } else if (EditorNode::get_singleton()->get_editor_selection()->get_selection().size() == 1) { Node *n = EditorNode::get_singleton()->get_editor_selection()->get_selected_node_list()[0]; if (n->get_script().is_null()) { button_create_script->show(); - button_clear_script->hide(); + button_detach_script->hide(); } else { button_create_script->hide(); - button_clear_script->show(); + button_detach_script->show(); } } else { button_create_script->hide(); @@ -1902,11 +1902,11 @@ void SceneTreeDock::_update_script_button() { for (int i = 0; i < selection.size(); i++) { Node *n = Object::cast_to<Node>(selection[i]); if (!n->get_script().is_null()) { - button_clear_script->show(); + button_detach_script->show(); return; } } - button_clear_script->hide(); + button_detach_script->hide(); } } @@ -2458,7 +2458,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { } if (existing_script.is_valid() && existing_script_removable) { add_separator = true; - menu->add_icon_shortcut(get_theme_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT); + menu->add_icon_shortcut(get_theme_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/detach_script"), TOOL_DETACH_SCRIPT); } else if (full_selection.size() > 1) { bool script_exists = false; for (List<Node *>::Element *E = full_selection.front(); E; E = E->next()) { @@ -2470,7 +2470,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { if (script_exists) { add_separator = true; - menu->add_icon_shortcut(get_theme_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT); + menu->add_icon_shortcut(get_theme_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/detach_script"), TOOL_DETACH_SCRIPT); } } @@ -2816,7 +2816,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel ED_SHORTCUT("scene_tree/change_node_type", TTR("Change Type")); ED_SHORTCUT("scene_tree/attach_script", TTR("Attach Script")); ED_SHORTCUT("scene_tree/extend_script", TTR("Extend Script")); - ED_SHORTCUT("scene_tree/clear_script", TTR("Clear Script")); + ED_SHORTCUT("scene_tree/detach_script", TTR("Detach Script")); ED_SHORTCUT("scene_tree/move_up", TTR("Move Up"), KEY_MASK_CMD | KEY_UP); ED_SHORTCUT("scene_tree/move_down", TTR("Move Down"), KEY_MASK_CMD | KEY_DOWN); ED_SHORTCUT("scene_tree/duplicate", TTR("Duplicate"), KEY_MASK_CMD | KEY_D); @@ -2851,17 +2851,17 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel button_create_script = memnew(ToolButton); button_create_script->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected), make_binds(TOOL_ATTACH_SCRIPT, false)); - button_create_script->set_tooltip(TTR("Attach a new or existing script for the selected node.")); + button_create_script->set_tooltip(TTR("Attach a new or existing script to the selected node.")); button_create_script->set_shortcut(ED_GET_SHORTCUT("scene_tree/attach_script")); filter_hbc->add_child(button_create_script); button_create_script->hide(); - button_clear_script = memnew(ToolButton); - button_clear_script->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected), make_binds(TOOL_CLEAR_SCRIPT, false)); - button_clear_script->set_tooltip(TTR("Clear a script for the selected node.")); - button_clear_script->set_shortcut(ED_GET_SHORTCUT("scene_tree/clear_script")); - filter_hbc->add_child(button_clear_script); - button_clear_script->hide(); + button_detach_script = memnew(ToolButton); + button_detach_script->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected), make_binds(TOOL_DETACH_SCRIPT, false)); + button_detach_script->set_tooltip(TTR("Detach the script from the selected node.")); + button_detach_script->set_shortcut(ED_GET_SHORTCUT("scene_tree/detach_script")); + filter_hbc->add_child(button_detach_script); + button_detach_script->hide(); button_hb = memnew(HBoxContainer); vbc->add_child(button_hb); diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index 31ef1ce7d0..00b95c9853 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -66,7 +66,7 @@ class SceneTreeDock : public VBoxContainer { TOOL_REPLACE, TOOL_EXTEND_SCRIPT, TOOL_ATTACH_SCRIPT, - TOOL_CLEAR_SCRIPT, + TOOL_DETACH_SCRIPT, TOOL_MOVE_UP, TOOL_MOVE_DOWN, TOOL_DUPLICATE, @@ -110,7 +110,7 @@ class SceneTreeDock : public VBoxContainer { ToolButton *button_add; ToolButton *button_instance; ToolButton *button_create_script; - ToolButton *button_clear_script; + ToolButton *button_detach_script; Button *button_3d; |