Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions modules/gltf/doc_classes/GLTFDocumentExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@
Runs when converting the data from a Godot scene node. This method can be used to process the Godot scene node data into a format that can be used by [method _export_node].
</description>
</method>
<method name="_export_get_property_list" qualifiers="virtual">
<return type="Dictionary[]" />
<param index="0" name="root_node" type="Node" />
<description>
Runs prior to the export process. This method is run before [method _export_preflight] when exporting a scene from the editor, or it may not be run at all in other situations.
Unlike the rest of the export methods, this does not run when calling a [GLTFDocument]'s export methods in sequence with everything else, but rather runs before that entire process occurs, allowing configuration to occur beforehand, potentially minutes or hours in advance of [method _export_preflight]. This allows extensions to decide which properties to show in the editor export settings dialog based on the contents of the scene, hiding any settings that are not relevant for that scene. The [param root_node] parameter may be [code]null[/code], in which case all properties should be shown.
</description>
</method>
<method name="_export_node" qualifiers="virtual">
<return type="int" enum="Error" />
<param index="0" name="state" type="GLTFState" />
Expand Down
63 changes: 40 additions & 23 deletions modules/gltf/editor/editor_scene_exporter_gltf_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

#include "core/object/callable_mp.h"
#include "core/object/class_db.h"
#include "core/object/script_language.h"

const uint32_t PROP_EDITOR_SCRIPT_VAR = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_SCRIPT_VARIABLE;

Expand Down Expand Up @@ -155,8 +156,15 @@ String get_friendly_config_prefix(Ref<GLTFDocumentExtension> p_extension) {
if (!config_prefix.is_empty()) {
return config_prefix;
}
const Ref<Script> script = p_extension->get_script();
if (script.is_valid()) {
config_prefix = String(script->get_global_name()).trim_prefix("GLTFDocumentExtension").trim_suffix("GLTFDocumentExtension");
if (!config_prefix.is_empty()) {
return config_prefix;
}
}
const String class_name = p_extension->get_class_name();
config_prefix = class_name.trim_prefix("GLTFDocumentExtension").trim_suffix("GLTFDocumentExtension").capitalize();
config_prefix = class_name.trim_prefix("GLTFDocumentExtension").trim_suffix("GLTFDocumentExtension");
if (!config_prefix.is_empty()) {
return config_prefix;
}
Expand Down Expand Up @@ -187,33 +195,12 @@ void EditorSceneExporterGLTFSettings::generate_property_list(Ref<GLTFDocument> p
_property_list.clear();
_document = p_document;
String image_format_hint_string = "None,PNG,JPEG";
// Add properties from all document extensions.
// If an extension allows saving images in different formats, add to the enum.
for (Ref<GLTFDocumentExtension> &extension : GLTFDocument::get_all_gltf_document_extensions()) {
const Callable on_prop_changed = callable_mp(this, &EditorSceneExporterGLTFSettings::_on_extension_property_list_changed);
if (!extension->is_connected(CoreStringName(property_list_changed), on_prop_changed)) {
extension->connect(CoreStringName(property_list_changed), on_prop_changed);
}
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<PropertyInfo> 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);
Expand All @@ -231,6 +218,36 @@ void EditorSceneExporterGLTFSettings::generate_property_list(Ref<GLTFDocument> p
PropertyInfo visibility_mode_prop = PropertyInfo(Variant::INT, "visibility_mode", PROPERTY_HINT_ENUM, "Include & Required,Include & Optional,Exclude");
_property_list.push_back(visibility_mode_prop);
}
// Now that the above code set up base glTF stuff, add properties from all document extensions.
for (Ref<GLTFDocumentExtension> &extension : GLTFDocument::get_all_gltf_document_extensions()) {
// Set up to listen for property changes.
const Callable on_prop_changed = callable_mp(this, &EditorSceneExporterGLTFSettings::_on_extension_property_list_changed);
if (!extension->is_connected(CoreStringName(property_list_changed), on_prop_changed)) {
extension->connect(CoreStringName(property_list_changed), on_prop_changed);
}
const String config_prefix = get_friendly_config_prefix(extension);
_config_name_to_extension_map[config_prefix] = extension;
// Look through the extension's properties and find the relevant ones.
List<PropertyInfo> export_prop_list = extension->export_get_property_list(p_root);
for (const PropertyInfo &prop : export_prop_list) {
PropertyInfo ext_prop = prop;
ext_prop.name = config_prefix + "/" + prop.name;
_property_list.push_back(ext_prop);
}
List<PropertyInfo> 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);
}
}
}
}

String EditorSceneExporterGLTFSettings::get_copyright() const {
Expand Down
14 changes: 14 additions & 0 deletions modules/gltf/extensions/gltf_document_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ void GLTFDocumentExtension::_bind_methods() {
GDVIRTUAL_BIND(_import_node, "state", "gltf_node", "json", "node");
GDVIRTUAL_BIND(_import_post, "state", "root");
// Export process.
GDVIRTUAL_BIND(_export_get_property_list, "root_node");
GDVIRTUAL_BIND(_export_preflight, "state", "root");
GDVIRTUAL_BIND(_convert_scene_node, "state", "gltf_node", "scene_node");
GDVIRTUAL_BIND(_export_post_convert, "state", "root");
Expand Down Expand Up @@ -151,6 +152,19 @@ Error GLTFDocumentExtension::import_post(Ref<GLTFState> p_state, Node *p_root) {
}

// Export process.
List<PropertyInfo> GLTFDocumentExtension::export_get_property_list(Node *p_root_node) {
TypedArray<Dictionary> ret_dicts;
GDVIRTUAL_CALL(_export_get_property_list, p_root_node, ret_dicts);
List<PropertyInfo> ret;
if (ret_dicts.is_empty()) {
return ret;
}
for (int i = 0; i < ret_dicts.size(); i++) {
ret.push_back(PropertyInfo::from_dict(ret_dicts[i]));
}
return ret;
}

Error GLTFDocumentExtension::export_preflight(Ref<GLTFState> p_state, Node *p_root) {
ERR_FAIL_NULL_V(p_root, ERR_INVALID_PARAMETER);
Error err = OK;
Expand Down
2 changes: 2 additions & 0 deletions modules/gltf/extensions/gltf_document_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class GLTFDocumentExtension : public Resource {
virtual Error import_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &r_json, Node *p_node);
virtual Error import_post(Ref<GLTFState> p_state, Node *p_node);
// Export process.
virtual List<PropertyInfo> export_get_property_list(Node *p_root_node);
virtual Error export_preflight(Ref<GLTFState> p_state, Node *p_root);
virtual void convert_scene_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Node *p_scene_node);
virtual Error export_post_convert(Ref<GLTFState> p_state, Node *p_root);
Expand All @@ -81,6 +82,7 @@ class GLTFDocumentExtension : public Resource {
GDVIRTUAL4R(Error, _import_node, Ref<GLTFState>, Ref<GLTFNode>, Dictionary, Node *);
GDVIRTUAL2R(Error, _import_post, Ref<GLTFState>, Node *);
// Export process.
GDVIRTUAL1R(TypedArray<Dictionary>, _export_get_property_list, Node *);
GDVIRTUAL2R(Error, _export_preflight, Ref<GLTFState>, Node *);
GDVIRTUAL3(_convert_scene_node, Ref<GLTFState>, Ref<GLTFNode>, Node *);
GDVIRTUAL2R(Error, _export_post_convert, Ref<GLTFState>, Node *);
Expand Down
Loading