diff --git a/modules/gltf/doc_classes/GLTFDocument.xml b/modules/gltf/doc_classes/GLTFDocument.xml
index f5066ba4f1c..1b52a822981 100644
--- a/modules/gltf/doc_classes/GLTFDocument.xml
+++ b/modules/gltf/doc_classes/GLTFDocument.xml
@@ -84,7 +84,7 @@
Takes a [GLTFState] object through the [param state] parameter and writes a glTF file to the filesystem.
- [b]Note:[/b] The extension of the glTF file determines if it is a .glb binary file or a .gltf file.
+ [b]Note:[/b] The extension of the glTF file determines if it is a .glb binary file or a .gltf text file.
diff --git a/modules/gltf/editor/editor_scene_exporter_gltf_plugin.cpp b/modules/gltf/editor/editor_scene_exporter_gltf_plugin.cpp
index 83c7f463df3..6975bc12283 100644
--- a/modules/gltf/editor/editor_scene_exporter_gltf_plugin.cpp
+++ b/modules/gltf/editor/editor_scene_exporter_gltf_plugin.cpp
@@ -32,12 +32,14 @@
#ifdef TOOLS_ENABLED
-#include "../gltf_document.h"
+#include "editor_scene_exporter_gltf_settings.h"
#include "editor/editor_file_system.h"
+#include "editor/editor_inspector.h"
#include "editor/editor_node.h"
+#include "editor/editor_scale.h"
#include "editor/gui/editor_file_dialog.h"
-#include "scene/gui/popup_menu.h"
+#include "editor/import/scene_import_settings.h"
String SceneExporterGLTFPlugin::get_name() const {
return "ConvertGLTF2";
@@ -48,59 +50,72 @@ bool SceneExporterGLTFPlugin::has_main_screen() const {
}
SceneExporterGLTFPlugin::SceneExporterGLTFPlugin() {
- file_export_lib = memnew(EditorFileDialog);
- EditorNode::get_singleton()->get_gui_base()->add_child(file_export_lib);
- file_export_lib->connect("file_selected", callable_mp(this, &SceneExporterGLTFPlugin::_gltf2_dialog_action));
- file_export_lib->set_title(TTR("Export Library"));
- file_export_lib->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
- file_export_lib->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
- file_export_lib->clear_filters();
- file_export_lib->add_filter("*.glb");
- file_export_lib->add_filter("*.gltf");
- file_export_lib->set_title(TTR("Export Scene to glTF 2.0 File"));
-
+ _gltf_document.instantiate();
+ // Set up the file dialog.
+ _file_dialog = memnew(EditorFileDialog);
+ _file_dialog->connect("file_selected", callable_mp(this, &SceneExporterGLTFPlugin::_export_scene_as_gltf));
+ _file_dialog->set_title(TTR("Export Library"));
+ _file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
+ _file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
+ _file_dialog->clear_filters();
+ _file_dialog->add_filter("*.glb");
+ _file_dialog->add_filter("*.gltf");
+ _file_dialog->set_title(TTR("Export Scene to glTF 2.0 File"));
+ EditorNode::get_singleton()->get_gui_base()->add_child(_file_dialog);
+ // Set up the export settings menu.
+ _export_settings.instantiate();
+ _export_settings->generate_property_list(_gltf_document);
+ _settings_inspector = memnew(EditorInspector);
+ _settings_inspector->set_custom_minimum_size(Size2(350, 300) * EDSCALE);
+ _file_dialog->add_side_menu(_settings_inspector, TTR("Export Settings:"));
+ // Add a button to the Scene -> Export menu to pop up the settings dialog.
PopupMenu *menu = get_export_as_menu();
int idx = menu->get_item_count();
menu->add_item(TTR("glTF 2.0 Scene..."));
- menu->set_item_metadata(idx, callable_mp(this, &SceneExporterGLTFPlugin::convert_scene_to_gltf2));
+ menu->set_item_metadata(idx, callable_mp(this, &SceneExporterGLTFPlugin::_popup_gltf_export_dialog));
}
-void SceneExporterGLTFPlugin::_gltf2_dialog_action(String p_file) {
+void SceneExporterGLTFPlugin::_popup_gltf_export_dialog() {
+ Node *root = EditorNode::get_singleton()->get_tree()->get_edited_scene_root();
+ if (!root) {
+ EditorNode::get_singleton()->show_accept(TTR("This operation can't be done without a scene."), TTR("OK"));
+ return;
+ }
+ // Set the file dialog's file name to the scene name.
+ String filename = String(root->get_scene_file_path().get_file().get_basename());
+ if (filename.is_empty()) {
+ filename = root->get_name();
+ }
+ _file_dialog->set_current_file(filename + String(".gltf"));
+ // Generate and refresh the export settings.
+ _export_settings->generate_property_list(_gltf_document);
+ _settings_inspector->edit(nullptr);
+ _settings_inspector->edit(_export_settings.ptr());
+ // Show the file dialog.
+ _file_dialog->popup_centered_ratio();
+}
+
+void SceneExporterGLTFPlugin::_export_scene_as_gltf(const String &p_file_path) {
Node *root = EditorNode::get_singleton()->get_tree()->get_edited_scene_root();
if (!root) {
EditorNode::get_singleton()->show_accept(TTR("This operation can't be done without a scene."), TTR("OK"));
return;
}
List deps;
- Ref doc;
- doc.instantiate();
Ref state;
state.instantiate();
+ state->set_copyright(_export_settings->get_copyright());
int32_t flags = 0;
flags |= EditorSceneFormatImporter::IMPORT_USE_NAMED_SKIN_BINDS;
- Error err = doc->append_from_scene(root, state, flags);
+ Error err = _gltf_document->append_from_scene(root, state, flags);
if (err != OK) {
ERR_PRINT(vformat("glTF2 save scene error %s.", itos(err)));
}
- err = doc->write_to_filesystem(state, p_file);
+ err = _gltf_document->write_to_filesystem(state, p_file_path);
if (err != OK) {
ERR_PRINT(vformat("glTF2 save scene error %s.", itos(err)));
}
EditorFileSystem::get_singleton()->scan_changes();
}
-void SceneExporterGLTFPlugin::convert_scene_to_gltf2() {
- Node *root = EditorNode::get_singleton()->get_tree()->get_edited_scene_root();
- if (!root) {
- EditorNode::get_singleton()->show_accept(TTR("This operation can't be done without a scene."), TTR("OK"));
- return;
- }
- String filename = String(root->get_scene_file_path().get_file().get_basename());
- if (filename.is_empty()) {
- filename = root->get_name();
- }
- file_export_lib->set_current_file(filename + String(".gltf"));
- file_export_lib->popup_centered_ratio();
-}
-
#endif // TOOLS_ENABLED
diff --git a/modules/gltf/editor/editor_scene_exporter_gltf_plugin.h b/modules/gltf/editor/editor_scene_exporter_gltf_plugin.h
index f92b3c51802..683ff6d4f66 100644
--- a/modules/gltf/editor/editor_scene_exporter_gltf_plugin.h
+++ b/modules/gltf/editor/editor_scene_exporter_gltf_plugin.h
@@ -33,18 +33,23 @@
#ifdef TOOLS_ENABLED
-#include "editor_scene_importer_gltf.h"
+#include "../gltf_document.h"
+#include "editor_scene_exporter_gltf_settings.h"
#include "editor/editor_plugin.h"
class EditorFileDialog;
+class EditorInspector;
class SceneExporterGLTFPlugin : public EditorPlugin {
GDCLASS(SceneExporterGLTFPlugin, EditorPlugin);
- EditorFileDialog *file_export_lib = nullptr;
- void _gltf2_dialog_action(String p_file);
- void convert_scene_to_gltf2();
+ Ref _gltf_document;
+ Ref _export_settings;
+ EditorInspector *_settings_inspector = nullptr;
+ EditorFileDialog *_file_dialog = nullptr;
+ void _popup_gltf_export_dialog();
+ void _export_scene_as_gltf(const String &p_file_path);
public:
virtual String get_name() const override;
diff --git a/modules/gltf/editor/editor_scene_exporter_gltf_settings.cpp b/modules/gltf/editor/editor_scene_exporter_gltf_settings.cpp
new file mode 100644
index 00000000000..b0283b0c557
--- /dev/null
+++ b/modules/gltf/editor/editor_scene_exporter_gltf_settings.cpp
@@ -0,0 +1,176 @@
+/**************************************************************************/
+/* editor_scene_exporter_gltf_settings.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 "editor_scene_exporter_gltf_settings.h"
+
+const uint32_t PROP_EDITOR_SCRIPT_VAR = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_SCRIPT_VARIABLE;
+
+bool EditorSceneExporterGLTFSettings::_set(const StringName &p_name, const Variant &p_value) {
+ String name_str = String(p_name);
+ if (name_str.contains("/")) {
+ return _set_extension_setting(name_str, p_value);
+ }
+ if (p_name == StringName("image_format")) {
+ _document->set_image_format(p_value);
+ emit_signal("property_list_changed");
+ return true;
+ }
+ if (p_name == StringName("lossy_quality")) {
+ _document->set_lossy_quality(p_value);
+ return true;
+ }
+ if (p_name == StringName("root_node_mode")) {
+ _document->set_root_node_mode((GLTFDocument::RootNodeMode)(int64_t)p_value);
+ return true;
+ }
+ return false;
+}
+
+bool EditorSceneExporterGLTFSettings::_get(const StringName &p_name, Variant &r_ret) const {
+ String name_str = String(p_name);
+ if (name_str.contains("/")) {
+ return _get_extension_setting(name_str, r_ret);
+ }
+ if (p_name == StringName("image_format")) {
+ r_ret = _document->get_image_format();
+ return true;
+ }
+ if (p_name == StringName("lossy_quality")) {
+ r_ret = _document->get_lossy_quality();
+ return true;
+ }
+ if (p_name == StringName("root_node_mode")) {
+ r_ret = _document->get_root_node_mode();
+ return true;
+ }
+ return false;
+}
+
+void EditorSceneExporterGLTFSettings::_get_property_list(List *p_list) const {
+ for (PropertyInfo prop : _property_list) {
+ if (prop.name == "lossy_quality") {
+ String image_format = get("image_format");
+ bool is_image_format_lossy = image_format == "JPEG" || image_format.findn("Lossy") != -1;
+ prop.usage = is_image_format_lossy ? PROPERTY_USAGE_DEFAULT : PROPERTY_USAGE_STORAGE;
+ }
+ p_list->push_back(prop);
+ }
+}
+
+bool EditorSceneExporterGLTFSettings::_set_extension_setting(const String &p_name_str, const Variant &p_value) {
+ PackedStringArray split = String(p_name_str).split("/", true, 1);
+ if (!_config_name_to_extension_map.has(split[0])) {
+ return false;
+ }
+ Ref extension = _config_name_to_extension_map[split[0]];
+ bool valid;
+ extension->set(split[1], p_value, &valid);
+ return valid;
+}
+
+bool EditorSceneExporterGLTFSettings::_get_extension_setting(const String &p_name_str, Variant &r_ret) const {
+ PackedStringArray split = String(p_name_str).split("/", true, 1);
+ if (!_config_name_to_extension_map.has(split[0])) {
+ return false;
+ }
+ Ref extension = _config_name_to_extension_map[split[0]];
+ bool valid;
+ r_ret = extension->get(split[1], &valid);
+ return valid;
+}
+
+String get_friendly_config_prefix(Ref p_extension) {
+ String config_prefix = p_extension->get_name();
+ if (!config_prefix.is_empty()) {
+ return config_prefix;
+ }
+ const String class_name = p_extension->get_class_name();
+ config_prefix = class_name.trim_prefix("GLTFDocumentExtension").capitalize();
+ if (!config_prefix.is_empty()) {
+ return config_prefix;
+ }
+ PackedStringArray supported_extensions = p_extension->get_supported_extensions();
+ if (supported_extensions.size() > 0) {
+ return supported_extensions[0];
+ }
+ return "Unknown GLTFDocumentExtension";
+}
+
+// Run this before popping up the export settings, because the extensions may have changed.
+void EditorSceneExporterGLTFSettings::generate_property_list(Ref p_document) {
+ _property_list.clear();
+ _document = p_document;
+ String image_format_hint_string = "None,PNG,JPEG";
+ // Add properties from all document extensions.
+ for (Ref &extension : GLTFDocument::get_all_gltf_document_extensions()) {
+ const String config_prefix = get_friendly_config_prefix(extension);
+ _config_name_to_extension_map[config_prefix] = extension;
+ // If the extension allows saving in different image formats, add to the enum.
+ PackedStringArray saveable_image_formats = extension->get_saveable_image_formats();
+ for (int i = 0; i < saveable_image_formats.size(); i++) {
+ image_format_hint_string += "," + saveable_image_formats[i];
+ }
+ // Look through the extension's properties and find the relevant ones.
+ List ext_prop_list;
+ extension->get_property_list(&ext_prop_list);
+ for (const PropertyInfo &prop : ext_prop_list) {
+ // We only want properties that will show up in the exporter
+ // settings list. Exclude Resource's properties, as they are
+ // not relevant to the exporter. Include any user-defined script
+ // variables exposed to the editor (PROP_EDITOR_SCRIPT_VAR).
+ if ((prop.usage & PROP_EDITOR_SCRIPT_VAR) == PROP_EDITOR_SCRIPT_VAR) {
+ PropertyInfo ext_prop = prop;
+ ext_prop.name = config_prefix + "/" + prop.name;
+ _property_list.push_back(ext_prop);
+ }
+ }
+ }
+ // Add top-level properties (in addition to what _bind_methods registers).
+ PropertyInfo image_format_prop = PropertyInfo(Variant::STRING, "image_format", PROPERTY_HINT_ENUM, image_format_hint_string);
+ _property_list.push_back(image_format_prop);
+ PropertyInfo lossy_quality_prop = PropertyInfo(Variant::FLOAT, "lossy_quality", PROPERTY_HINT_RANGE, "0,1,0.01");
+ _property_list.push_back(lossy_quality_prop);
+ PropertyInfo root_node_mode_prop = PropertyInfo(Variant::INT, "root_node_mode", PROPERTY_HINT_ENUM, "Single Root,Keep Root,Multi Root");
+ _property_list.push_back(root_node_mode_prop);
+}
+
+String EditorSceneExporterGLTFSettings::get_copyright() const {
+ return _copyright;
+}
+
+void EditorSceneExporterGLTFSettings::set_copyright(const String &p_copyright) {
+ _copyright = p_copyright;
+}
+
+void EditorSceneExporterGLTFSettings::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_copyright"), &EditorSceneExporterGLTFSettings::get_copyright);
+ ClassDB::bind_method(D_METHOD("set_copyright", "copyright"), &EditorSceneExporterGLTFSettings::set_copyright);
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "copyright", PROPERTY_HINT_PLACEHOLDER_TEXT, "Example: 2014 Godette"), "set_copyright", "get_copyright");
+}
diff --git a/modules/gltf/editor/editor_scene_exporter_gltf_settings.h b/modules/gltf/editor/editor_scene_exporter_gltf_settings.h
new file mode 100644
index 00000000000..6032932367c
--- /dev/null
+++ b/modules/gltf/editor/editor_scene_exporter_gltf_settings.h
@@ -0,0 +1,64 @@
+/**************************************************************************/
+/* editor_scene_exporter_gltf_settings.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 EDITOR_SCENE_EXPORTER_GLTF_SETTINGS_H
+#define EDITOR_SCENE_EXPORTER_GLTF_SETTINGS_H
+
+#ifdef TOOLS_ENABLED
+
+#include "../gltf_document.h"
+
+class EditorSceneExporterGLTFSettings : public RefCounted {
+ GDCLASS(EditorSceneExporterGLTFSettings, RefCounted);
+ List _property_list;
+ Ref _document;
+ HashMap> _config_name_to_extension_map;
+
+ String _copyright;
+
+protected:
+ static void _bind_methods();
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_ret) const;
+ void _get_property_list(List *p_list) const;
+
+ bool _set_extension_setting(const String &p_name_str, const Variant &p_value);
+ bool _get_extension_setting(const String &p_name_str, Variant &r_ret) const;
+
+public:
+ void generate_property_list(Ref p_document);
+
+ String get_copyright() const;
+ void set_copyright(const String &p_copyright);
+};
+
+#endif // TOOLS_ENABLED
+
+#endif // EDITOR_SCENE_EXPORTER_GLTF_SETTINGS_H
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index 4060f7f6268..030c3f88b0d 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -3658,141 +3658,143 @@ Error GLTFDocument::_serialize_materials(Ref p_state) {
mr["metallicFactor"] = base_material->get_metallic();
mr["roughnessFactor"] = base_material->get_roughness();
- bool has_roughness = base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS).is_valid() && base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS)->get_image().is_valid();
- bool has_ao = base_material->get_feature(BaseMaterial3D::FEATURE_AMBIENT_OCCLUSION) && base_material->get_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION).is_valid();
- bool has_metalness = base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC).is_valid() && base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC)->get_image().is_valid();
- if (has_ao || has_roughness || has_metalness) {
- Dictionary mrt;
- Ref roughness_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS);
- BaseMaterial3D::TextureChannel roughness_channel = base_material->get_roughness_texture_channel();
- Ref metallic_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC);
- BaseMaterial3D::TextureChannel metalness_channel = base_material->get_metallic_texture_channel();
- Ref ao_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION);
- BaseMaterial3D::TextureChannel ao_channel = base_material->get_ao_texture_channel();
- Ref orm_texture;
- orm_texture.instantiate();
- Ref orm_image;
- orm_image.instantiate();
- int32_t height = 0;
- int32_t width = 0;
- Ref ao_image;
- if (has_ao) {
- height = ao_texture->get_height();
- width = ao_texture->get_width();
- ao_image = ao_texture->get_image();
- Ref img_tex = ao_image;
- if (img_tex.is_valid()) {
- ao_image = img_tex->get_image();
- }
- if (ao_image->is_compressed()) {
- ao_image->decompress();
- }
- }
- Ref roughness_image;
- if (has_roughness) {
- height = roughness_texture->get_height();
- width = roughness_texture->get_width();
- roughness_image = roughness_texture->get_image();
- Ref img_tex = roughness_image;
- if (img_tex.is_valid()) {
- roughness_image = img_tex->get_image();
- }
- if (roughness_image->is_compressed()) {
- roughness_image->decompress();
- }
- }
- Ref metallness_image;
- if (has_metalness) {
- height = metallic_texture->get_height();
- width = metallic_texture->get_width();
- metallness_image = metallic_texture->get_image();
- Ref img_tex = metallness_image;
- if (img_tex.is_valid()) {
- metallness_image = img_tex->get_image();
- }
- if (metallness_image->is_compressed()) {
- metallness_image->decompress();
- }
- }
- Ref albedo_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ALBEDO);
- if (albedo_texture.is_valid() && albedo_texture->get_image().is_valid()) {
- height = albedo_texture->get_height();
- width = albedo_texture->get_width();
- }
- orm_image->initialize_data(width, height, false, Image::FORMAT_RGBA8);
- if (ao_image.is_valid() && ao_image->get_size() != Vector2(width, height)) {
- ao_image->resize(width, height, Image::INTERPOLATE_LANCZOS);
- }
- if (roughness_image.is_valid() && roughness_image->get_size() != Vector2(width, height)) {
- roughness_image->resize(width, height, Image::INTERPOLATE_LANCZOS);
- }
- if (metallness_image.is_valid() && metallness_image->get_size() != Vector2(width, height)) {
- metallness_image->resize(width, height, Image::INTERPOLATE_LANCZOS);
- }
- for (int32_t h = 0; h < height; h++) {
- for (int32_t w = 0; w < width; w++) {
- Color c = Color(1.0f, 1.0f, 1.0f);
- if (has_ao) {
- if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == ao_channel) {
- c.r = ao_image->get_pixel(w, h).r;
- } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == ao_channel) {
- c.r = ao_image->get_pixel(w, h).g;
- } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == ao_channel) {
- c.r = ao_image->get_pixel(w, h).b;
- } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == ao_channel) {
- c.r = ao_image->get_pixel(w, h).a;
- }
- }
- if (has_roughness) {
- if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == roughness_channel) {
- c.g = roughness_image->get_pixel(w, h).r;
- } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == roughness_channel) {
- c.g = roughness_image->get_pixel(w, h).g;
- } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == roughness_channel) {
- c.g = roughness_image->get_pixel(w, h).b;
- } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == roughness_channel) {
- c.g = roughness_image->get_pixel(w, h).a;
- }
- }
- if (has_metalness) {
- if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == metalness_channel) {
- c.b = metallness_image->get_pixel(w, h).r;
- } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == metalness_channel) {
- c.b = metallness_image->get_pixel(w, h).g;
- } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == metalness_channel) {
- c.b = metallness_image->get_pixel(w, h).b;
- } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == metalness_channel) {
- c.b = metallness_image->get_pixel(w, h).a;
- }
- }
- orm_image->set_pixel(w, h, c);
- }
- }
- orm_image->generate_mipmaps();
- orm_texture->set_image(orm_image);
- GLTFTextureIndex orm_texture_index = -1;
+ if (_image_format != "None") {
+ bool has_roughness = base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS).is_valid() && base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS)->get_image().is_valid();
+ bool has_ao = base_material->get_feature(BaseMaterial3D::FEATURE_AMBIENT_OCCLUSION) && base_material->get_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION).is_valid();
+ bool has_metalness = base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC).is_valid() && base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC)->get_image().is_valid();
if (has_ao || has_roughness || has_metalness) {
- orm_texture->set_name(material->get_name() + "_orm");
- orm_texture_index = _set_texture(p_state, orm_texture, base_material->get_texture_filter(), base_material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
- }
- if (has_ao) {
- Dictionary occt;
- occt["index"] = orm_texture_index;
- d["occlusionTexture"] = occt;
- }
- if (has_roughness || has_metalness) {
- mrt["index"] = orm_texture_index;
- Dictionary extensions = _serialize_texture_transform_uv1(material);
- if (!extensions.is_empty()) {
- mrt["extensions"] = extensions;
- p_state->use_khr_texture_transform = true;
+ Dictionary mrt;
+ Ref roughness_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS);
+ BaseMaterial3D::TextureChannel roughness_channel = base_material->get_roughness_texture_channel();
+ Ref metallic_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC);
+ BaseMaterial3D::TextureChannel metalness_channel = base_material->get_metallic_texture_channel();
+ Ref ao_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION);
+ BaseMaterial3D::TextureChannel ao_channel = base_material->get_ao_texture_channel();
+ Ref orm_texture;
+ orm_texture.instantiate();
+ Ref orm_image;
+ orm_image.instantiate();
+ int32_t height = 0;
+ int32_t width = 0;
+ Ref ao_image;
+ if (has_ao) {
+ height = ao_texture->get_height();
+ width = ao_texture->get_width();
+ ao_image = ao_texture->get_image();
+ Ref img_tex = ao_image;
+ if (img_tex.is_valid()) {
+ ao_image = img_tex->get_image();
+ }
+ if (ao_image->is_compressed()) {
+ ao_image->decompress();
+ }
+ }
+ Ref roughness_image;
+ if (has_roughness) {
+ height = roughness_texture->get_height();
+ width = roughness_texture->get_width();
+ roughness_image = roughness_texture->get_image();
+ Ref img_tex = roughness_image;
+ if (img_tex.is_valid()) {
+ roughness_image = img_tex->get_image();
+ }
+ if (roughness_image->is_compressed()) {
+ roughness_image->decompress();
+ }
+ }
+ Ref metallness_image;
+ if (has_metalness) {
+ height = metallic_texture->get_height();
+ width = metallic_texture->get_width();
+ metallness_image = metallic_texture->get_image();
+ Ref img_tex = metallness_image;
+ if (img_tex.is_valid()) {
+ metallness_image = img_tex->get_image();
+ }
+ if (metallness_image->is_compressed()) {
+ metallness_image->decompress();
+ }
+ }
+ Ref albedo_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ALBEDO);
+ if (albedo_texture.is_valid() && albedo_texture->get_image().is_valid()) {
+ height = albedo_texture->get_height();
+ width = albedo_texture->get_width();
+ }
+ orm_image->initialize_data(width, height, false, Image::FORMAT_RGBA8);
+ if (ao_image.is_valid() && ao_image->get_size() != Vector2(width, height)) {
+ ao_image->resize(width, height, Image::INTERPOLATE_LANCZOS);
+ }
+ if (roughness_image.is_valid() && roughness_image->get_size() != Vector2(width, height)) {
+ roughness_image->resize(width, height, Image::INTERPOLATE_LANCZOS);
+ }
+ if (metallness_image.is_valid() && metallness_image->get_size() != Vector2(width, height)) {
+ metallness_image->resize(width, height, Image::INTERPOLATE_LANCZOS);
+ }
+ for (int32_t h = 0; h < height; h++) {
+ for (int32_t w = 0; w < width; w++) {
+ Color c = Color(1.0f, 1.0f, 1.0f);
+ if (has_ao) {
+ if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == ao_channel) {
+ c.r = ao_image->get_pixel(w, h).r;
+ } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == ao_channel) {
+ c.r = ao_image->get_pixel(w, h).g;
+ } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == ao_channel) {
+ c.r = ao_image->get_pixel(w, h).b;
+ } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == ao_channel) {
+ c.r = ao_image->get_pixel(w, h).a;
+ }
+ }
+ if (has_roughness) {
+ if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == roughness_channel) {
+ c.g = roughness_image->get_pixel(w, h).r;
+ } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == roughness_channel) {
+ c.g = roughness_image->get_pixel(w, h).g;
+ } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == roughness_channel) {
+ c.g = roughness_image->get_pixel(w, h).b;
+ } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == roughness_channel) {
+ c.g = roughness_image->get_pixel(w, h).a;
+ }
+ }
+ if (has_metalness) {
+ if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == metalness_channel) {
+ c.b = metallness_image->get_pixel(w, h).r;
+ } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == metalness_channel) {
+ c.b = metallness_image->get_pixel(w, h).g;
+ } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == metalness_channel) {
+ c.b = metallness_image->get_pixel(w, h).b;
+ } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == metalness_channel) {
+ c.b = metallness_image->get_pixel(w, h).a;
+ }
+ }
+ orm_image->set_pixel(w, h, c);
+ }
+ }
+ orm_image->generate_mipmaps();
+ orm_texture->set_image(orm_image);
+ GLTFTextureIndex orm_texture_index = -1;
+ if (has_ao || has_roughness || has_metalness) {
+ orm_texture->set_name(material->get_name() + "_orm");
+ orm_texture_index = _set_texture(p_state, orm_texture, base_material->get_texture_filter(), base_material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
+ }
+ if (has_ao) {
+ Dictionary occt;
+ occt["index"] = orm_texture_index;
+ d["occlusionTexture"] = occt;
+ }
+ if (has_roughness || has_metalness) {
+ mrt["index"] = orm_texture_index;
+ Dictionary extensions = _serialize_texture_transform_uv1(material);
+ if (!extensions.is_empty()) {
+ mrt["extensions"] = extensions;
+ p_state->use_khr_texture_transform = true;
+ }
+ mr["metallicRoughnessTexture"] = mrt;
}
- mr["metallicRoughnessTexture"] = mrt;
}
}
d["pbrMetallicRoughness"] = mr;
- if (base_material->get_feature(BaseMaterial3D::FEATURE_NORMAL_MAPPING)) {
+ if (base_material->get_feature(BaseMaterial3D::FEATURE_NORMAL_MAPPING) && _image_format != "None") {
Dictionary nt;
Ref tex;
tex.instantiate();
@@ -3845,7 +3847,7 @@ Error GLTFDocument::_serialize_materials(Ref p_state) {
d["emissiveFactor"] = arr;
}
- if (base_material->get_feature(BaseMaterial3D::FEATURE_EMISSION)) {
+ if (base_material->get_feature(BaseMaterial3D::FEATURE_EMISSION) && _image_format != "None") {
Dictionary et;
Ref emission_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_EMISSION);
GLTFTextureIndex gltf_texture_index = -1;
@@ -7336,6 +7338,10 @@ void GLTFDocument::unregister_all_gltf_document_extensions() {
all_document_extensions.clear();
}
+Vector[> GLTFDocument::get_all_gltf_document_extensions() {
+ return all_document_extensions;
+}
+
PackedByteArray GLTFDocument::_serialize_glb_buffer(Ref p_state, Error *r_err) {
Error err = _encode_buffer_glb(p_state, "");
if (r_err) {
diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h
index 7e378fe94db..f321bb71110 100644
--- a/modules/gltf/gltf_document.h
+++ b/modules/gltf/gltf_document.h
@@ -86,6 +86,7 @@ public:
static void register_gltf_document_extension(Ref p_extension, bool p_first_priority = false);
static void unregister_gltf_document_extension(Ref p_extension);
static void unregister_all_gltf_document_extensions();
+ static Vector][> get_all_gltf_document_extensions();
void set_naming_version(int p_version);
int get_naming_version() const;
]