summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2020-05-01 09:34:23 -0300
committerJuan Linietsky <reduzio@gmail.com>2020-05-10 15:59:09 -0300
commit1bea8e1eacc68bcedbd3f207395bccf11011dae2 (patch)
treeb75303a69491978c1e13360a3e6f355c5234dfe0 /editor
parent6a0473bcc23c096ef9ee929632a209761c2668f6 (diff)
New lightmapper
-Added LocalVector (needed it) -Added stb_rect_pack (It's pretty cool, we could probably use it for other stuff too) -Fixes and changes all around the place -Added library for 128 bits fixed point (required for Delaunay3D)
Diffstat (limited to 'editor')
-rw-r--r--editor/editor_node.cpp16
-rw-r--r--editor/import/resource_importer_layered_texture.cpp321
-rw-r--r--editor/import/resource_importer_layered_texture.h34
-rw-r--r--editor/import/resource_importer_scene.cpp7
-rw-r--r--editor/import/resource_importer_shader_file.cpp2
-rw-r--r--editor/import/resource_importer_texture.cpp113
-rw-r--r--editor/import/resource_importer_texture.h12
-rw-r--r--editor/node_3d_editor_gizmos.cpp315
-rw-r--r--editor/node_3d_editor_gizmos.h31
-rw-r--r--editor/plugins/baked_lightmap_editor_plugin.cpp69
-rw-r--r--editor/plugins/baked_lightmap_editor_plugin.h7
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp2
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp3
-rw-r--r--editor/plugins/texture_editor_plugin.cpp6
-rw-r--r--editor/plugins/texture_layered_editor_plugin.cpp286
-rw-r--r--editor/plugins/texture_layered_editor_plugin.h95
16 files changed, 972 insertions, 347 deletions
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/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 2a399087b2..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() {
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/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 1bf5999906..69f8efa86e 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -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