feat: godot-engine-source-4.3-stable

This commit is contained in:
Jan van der Weide 2025-01-17 16:36:38 +01:00
parent c59a7dcade
commit 7125d019b5
11149 changed files with 5070401 additions and 0 deletions

48
engine/modules/fbx/SCsub Normal file
View file

@ -0,0 +1,48 @@
#!/usr/bin/env python
Import("env")
Import("env_modules")
env_fbx = env_modules.Clone()
# Thirdparty source files
thirdparty_obj = []
thirdparty_dir = "#thirdparty/ufbx/"
thirdparty_sources = [thirdparty_dir + "ufbx.c"]
env_fbx.Prepend(CPPPATH=[thirdparty_dir])
env_thirdparty = env_fbx.Clone()
env_thirdparty.disable_warnings()
env_thirdparty.Append(
CPPDEFINES=[
"UFBX_NO_SUBDIVISION",
"UFBX_NO_TESSELLATION",
"UFBX_NO_GEOMETRY_CACHE",
"UFBX_NO_SCENE_EVALUATION",
"UFBX_NO_INDEX_GENERATION",
"UFBX_NO_SKINNING_EVALUATION",
"UFBX_NO_FORMAT_OBJ",
]
)
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
env.modules_sources += thirdparty_obj
# Godot source files
module_obj = []
env_fbx.add_source_files(module_obj, "*.cpp")
env_fbx.add_source_files(module_obj, "structures/*.cpp")
if env.editor_build:
env_fbx.add_source_files(module_obj, "editor/*.cpp")
env.modules_sources += module_obj
# Needed to force rebuilding the module files when the thirdparty library is updated.
env.Depends(module_obj, thirdparty_obj)

View file

@ -0,0 +1,20 @@
def can_build(env, platform):
env.module_add_dependencies("fbx", ["gltf"])
return not env["disable_3d"]
def configure(env):
pass
def get_doc_classes():
return [
"EditorSceneFormatImporterFBX2GLTF",
"EditorSceneFormatImporterUFBX",
"FBXDocument",
"FBXState",
]
def get_doc_path():
return "doc_classes"

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="EditorSceneFormatImporterFBX2GLTF" inherits="EditorSceneFormatImporter" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
Importer for the [code].fbx[/code] scene file format.
</brief_description>
<description>
Imports Autodesk FBX 3D scenes by way of converting them to glTF 2.0 using the FBX2glTF command line tool.
The location of the FBX2glTF binary is set via the [member EditorSettings.filesystem/import/fbx/fbx2gltf_path] editor setting.
This importer is only used if [member ProjectSettings.filesystem/import/fbx2gltf/enabled] is set to [code]true[/code].
</description>
<tutorials>
</tutorials>
</class>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="EditorSceneFormatImporterUFBX" inherits="EditorSceneFormatImporter" experimental="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
Import FBX files using the ufbx library.
</brief_description>
<description>
EditorSceneFormatImporterUFBX is designed to load FBX files and supports both binary and ASCII FBX files from version 3000 onward. This class supports various 3D object types like meshes, skins, blend shapes, materials, and rigging information. The class aims for feature parity with the official FBX SDK and supports FBX 7.4 specifications.
</description>
<tutorials>
</tutorials>
</class>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="FBXDocument" inherits="GLTFDocument" experimental="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
Handles FBX documents.
</brief_description>
<description>
The FBXDocument handles FBX documents. It provides methods to append data from buffers or files, generate scenes, and register/unregister document extensions.
When exporting FBX from Blender, use the "FBX Units Scale" option. The "FBX Units Scale" option sets the correct scale factor and avoids manual adjustments when re-importing into Blender, such as through glTF export.
</description>
<tutorials>
</tutorials>
</class>

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="FBXState" inherits="GLTFState" experimental="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
</brief_description>
<description>
The FBXState handles the state data imported from FBX files.
</description>
<tutorials>
</tutorials>
<members>
<member name="allow_geometry_helper_nodes" type="bool" setter="set_allow_geometry_helper_nodes" getter="get_allow_geometry_helper_nodes" default="false">
If [code]true[/code], the import process used auxiliary nodes called geometry helper nodes. These nodes help preserve the pivots and transformations of the original 3D model during import.
</member>
</members>
</class>

View file

@ -0,0 +1,150 @@
/**************************************************************************/
/* editor_scene_importer_fbx2gltf.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_importer_fbx2gltf.h"
#ifdef TOOLS_ENABLED
#include "editor_scene_importer_ufbx.h"
#include "modules/gltf/gltf_document.h"
#include "core/config/project_settings.h"
#include "editor/editor_settings.h"
uint32_t EditorSceneFormatImporterFBX2GLTF::get_import_flags() const {
return ImportFlags::IMPORT_SCENE | ImportFlags::IMPORT_ANIMATION;
}
void EditorSceneFormatImporterFBX2GLTF::get_extensions(List<String> *r_extensions) const {
r_extensions->push_back("fbx");
}
Node *EditorSceneFormatImporterFBX2GLTF::import_scene(const String &p_path, uint32_t p_flags,
const HashMap<StringName, Variant> &p_options,
List<String> *r_missing_deps, Error *r_err) {
// FIXME: Hack to work around GH-86309.
if (p_options.has("fbx/importer") && int(p_options["fbx/importer"]) == EditorSceneFormatImporterUFBX::FBX_IMPORTER_UFBX) {
Ref<EditorSceneFormatImporterUFBX> fbx2gltf_importer;
fbx2gltf_importer.instantiate();
Node *scene = fbx2gltf_importer->import_scene(p_path, p_flags, p_options, r_missing_deps, r_err);
if (r_err && *r_err == OK) {
return scene;
} else {
return nullptr;
}
}
// Get global paths for source and sink.
// Don't use `c_escape()` as it can generate broken paths. These paths will be
// enclosed in double quotes by OS::execute(), so we only need to escape those.
// `c_escape_multiline()` seems to do this (escapes `\` and `"` only).
const String source_global = ProjectSettings::get_singleton()->globalize_path(p_path).c_escape_multiline();
const String sink = ProjectSettings::get_singleton()->get_imported_files_path().path_join(
vformat("%s-%s.glb", p_path.get_file().get_basename(), p_path.md5_text()));
const String sink_global = ProjectSettings::get_singleton()->globalize_path(sink).c_escape_multiline();
// Run fbx2gltf.
String fbx2gltf_path = EDITOR_GET("filesystem/import/fbx/fbx2gltf_path");
List<String> args;
args.push_back("--pbr-metallic-roughness");
args.push_back("--input");
args.push_back(source_global);
args.push_back("--output");
args.push_back(sink_global);
args.push_back("--binary");
String standard_out;
int ret;
OS::get_singleton()->execute(fbx2gltf_path, args, &standard_out, &ret, true);
print_verbose(fbx2gltf_path);
print_verbose(standard_out);
if (ret != 0) {
if (r_err) {
*r_err = ERR_SCRIPT_FAILED;
}
ERR_PRINT(vformat("FBX conversion to glTF failed with error: %d.", ret));
return nullptr;
}
// Import the generated glTF.
// Use GLTFDocument instead of glTF importer to keep image references.
Ref<GLTFDocument> gltf;
gltf.instantiate();
Ref<GLTFState> state;
state.instantiate();
if (p_options.has(SNAME("nodes/import_as_skeleton_bones")) ? (bool)p_options[SNAME("nodes/import_as_skeleton_bones")] : false) {
state->set_import_as_skeleton_bones(true);
}
print_verbose(vformat("glTF path: %s", sink));
Error err = gltf->append_from_file(sink, state, p_flags, p_path.get_base_dir());
if (err != OK) {
if (r_err) {
*r_err = FAILED;
}
return nullptr;
}
#ifndef DISABLE_DEPRECATED
bool trimming = p_options.has("animation/trimming") ? (bool)p_options["animation/trimming"] : false;
return gltf->generate_scene(state, (float)p_options["animation/fps"], trimming, false);
#else
return gltf->generate_scene(state, (float)p_options["animation/fps"], (bool)p_options["animation/trimming"], false);
#endif
}
Variant EditorSceneFormatImporterFBX2GLTF::get_option_visibility(const String &p_path, bool p_for_animation,
const String &p_option, const HashMap<StringName, Variant> &p_options) {
// Remove all the FBX options except for 'fbx/importer' if the importer is fbx2gltf.
// These options are available only for ufbx.
if (p_option.begins_with("fbx/") && p_option != "fbx/importer" && p_options.has("fbx/importer") && int(p_options["fbx/importer"]) == EditorSceneFormatImporterUFBX::FBX_IMPORTER_FBX2GLTF) {
return false;
}
return true;
}
#define ADD_OPTION_ENUM(PATH, ENUM_HINT, VALUE) \
r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, SNAME(PATH), PROPERTY_HINT_ENUM, ENUM_HINT), VALUE));
void EditorSceneFormatImporterFBX2GLTF::get_import_options(const String &p_path,
List<ResourceImporter::ImportOption> *r_options) {
}
void EditorSceneFormatImporterFBX2GLTF::handle_compatibility_options(HashMap<StringName, Variant> &p_import_params) const {
if (!p_import_params.has("fbx/importer")) {
p_import_params["fbx/importer"] = EditorSceneFormatImporterUFBX::FBX_IMPORTER_UFBX;
}
}
#endif // TOOLS_ENABLED

View file

@ -0,0 +1,59 @@
/**************************************************************************/
/* editor_scene_importer_fbx2gltf.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_IMPORTER_FBX2GLTF_H
#define EDITOR_SCENE_IMPORTER_FBX2GLTF_H
#ifdef TOOLS_ENABLED
#include "editor/import/3d/resource_importer_scene.h"
class Animation;
class Node;
class EditorSceneFormatImporterFBX2GLTF : public EditorSceneFormatImporter {
GDCLASS(EditorSceneFormatImporterFBX2GLTF, EditorSceneFormatImporter);
public:
virtual uint32_t get_import_flags() const override;
virtual void get_extensions(List<String> *r_extensions) const override;
virtual Node *import_scene(const String &p_path, uint32_t p_flags,
const HashMap<StringName, Variant> &p_options,
List<String> *r_missing_deps, Error *r_err = nullptr) override;
virtual void get_import_options(const String &p_path,
List<ResourceImporter::ImportOption> *r_options) override;
virtual Variant get_option_visibility(const String &p_path, bool p_for_animation, const String &p_option,
const HashMap<StringName, Variant> &p_options) override;
virtual void handle_compatibility_options(HashMap<StringName, Variant> &p_import_params) const override;
};
#endif // TOOLS_ENABLED
#endif // EDITOR_SCENE_IMPORTER_FBX2GLTF_H

View file

@ -0,0 +1,112 @@
/**************************************************************************/
/* editor_scene_importer_ufbx.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_importer_ufbx.h"
#ifdef TOOLS_ENABLED
#include "../fbx_document.h"
#include "editor_scene_importer_fbx2gltf.h"
#include "core/config/project_settings.h"
uint32_t EditorSceneFormatImporterUFBX::get_import_flags() const {
return ImportFlags::IMPORT_SCENE | ImportFlags::IMPORT_ANIMATION;
}
void EditorSceneFormatImporterUFBX::get_extensions(List<String> *r_extensions) const {
r_extensions->push_back("fbx");
}
Node *EditorSceneFormatImporterUFBX::import_scene(const String &p_path, uint32_t p_flags,
const HashMap<StringName, Variant> &p_options,
List<String> *r_missing_deps, Error *r_err) {
// FIXME: Hack to work around GH-86309.
if (p_options.has("fbx/importer") && int(p_options["fbx/importer"]) == FBX_IMPORTER_FBX2GLTF && GLOBAL_GET("filesystem/import/fbx2gltf/enabled")) {
Ref<EditorSceneFormatImporterFBX2GLTF> fbx2gltf_importer;
fbx2gltf_importer.instantiate();
Node *scene = fbx2gltf_importer->import_scene(p_path, p_flags, p_options, r_missing_deps, r_err);
if (r_err && *r_err == OK) {
return scene;
} else {
return nullptr;
}
}
Ref<FBXDocument> fbx;
fbx.instantiate();
Ref<FBXState> state;
state.instantiate();
print_verbose(vformat("FBX path: %s", p_path));
String path = ProjectSettings::get_singleton()->globalize_path(p_path);
bool allow_geometry_helper_nodes = p_options.has("fbx/allow_geometry_helper_nodes") ? (bool)p_options["fbx/allow_geometry_helper_nodes"] : false;
if (allow_geometry_helper_nodes) {
state->set_allow_geometry_helper_nodes(allow_geometry_helper_nodes);
}
if (p_options.has("fbx/embedded_image_handling")) {
int32_t enum_option = p_options["fbx/embedded_image_handling"];
state->set_handle_binary_image(enum_option);
}
if (p_options.has(SNAME("nodes/import_as_skeleton_bones")) ? (bool)p_options[SNAME("nodes/import_as_skeleton_bones")] : false) {
state->set_import_as_skeleton_bones(true);
}
p_flags |= EditorSceneFormatImporter::IMPORT_USE_NAMED_SKIN_BINDS;
state->set_bake_fps(p_options["animation/fps"]);
Error err = fbx->append_from_file(path, state, p_flags, p_path.get_base_dir());
if (err != OK) {
if (r_err) {
*r_err = FAILED;
}
return nullptr;
}
return fbx->generate_scene(state, state->get_bake_fps(), (bool)p_options["animation/trimming"], false);
}
Variant EditorSceneFormatImporterUFBX::get_option_visibility(const String &p_path, bool p_for_animation,
const String &p_option, const HashMap<StringName, Variant> &p_options) {
return true;
}
void EditorSceneFormatImporterUFBX::get_import_options(const String &p_path,
List<ResourceImporter::ImportOption> *r_options) {
// Returns all the options when path is empty because that means it's for the Project Settings.
if (p_path.is_empty() || p_path.get_extension().to_lower() == "fbx") {
r_options->push_back(ResourceImporterScene::ImportOption(PropertyInfo(Variant::INT, "fbx/importer", PROPERTY_HINT_ENUM, "ufbx,FBX2glTF"), FBX_IMPORTER_UFBX));
r_options->push_back(ResourceImporterScene::ImportOption(PropertyInfo(Variant::BOOL, "fbx/allow_geometry_helper_nodes"), false));
r_options->push_back(ResourceImporterScene::ImportOption(PropertyInfo(Variant::INT, "fbx/embedded_image_handling", PROPERTY_HINT_ENUM, "Discard All Textures,Extract Textures,Embed as Basis Universal,Embed as Uncompressed", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), FBXState::HANDLE_BINARY_EXTRACT_TEXTURES));
}
}
void EditorSceneFormatImporterUFBX::handle_compatibility_options(HashMap<StringName, Variant> &p_import_params) const {
if (!p_import_params.has("fbx/importer")) {
p_import_params["fbx/importer"] = EditorSceneFormatImporterUFBX::FBX_IMPORTER_FBX2GLTF;
}
}
#endif // TOOLS_ENABLED

View file

@ -0,0 +1,62 @@
/**************************************************************************/
/* editor_scene_importer_ufbx.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_IMPORTER_UFBX_H
#define EDITOR_SCENE_IMPORTER_UFBX_H
#ifdef TOOLS_ENABLED
#include "editor/import/3d/resource_importer_scene.h"
class Animation;
class Node;
class EditorSceneFormatImporterUFBX : public EditorSceneFormatImporter {
GDCLASS(EditorSceneFormatImporterUFBX, EditorSceneFormatImporter);
public:
enum FBX_IMPORTER_TYPE {
FBX_IMPORTER_UFBX,
FBX_IMPORTER_FBX2GLTF,
};
virtual uint32_t get_import_flags() const override;
virtual void get_extensions(List<String> *r_extensions) const override;
virtual Node *import_scene(const String &p_path, uint32_t p_flags,
const HashMap<StringName, Variant> &p_options,
List<String> *r_missing_deps, Error *r_err = nullptr) override;
virtual void get_import_options(const String &p_path,
List<ResourceImporter::ImportOption> *r_options) override;
virtual Variant get_option_visibility(const String &p_path, bool p_for_animation, const String &p_option,
const HashMap<StringName, Variant> &p_options) override;
virtual void handle_compatibility_options(HashMap<StringName, Variant> &p_import_params) const override;
};
#endif // TOOLS_ENABLED
#endif // EDITOR_SCENE_IMPORTER_UFBX_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,106 @@
/**************************************************************************/
/* fbx_document.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 FBX_DOCUMENT_H
#define FBX_DOCUMENT_H
#include "fbx_state.h"
#include "modules/gltf/gltf_defines.h"
#include "modules/gltf/gltf_document.h"
#include <ufbx.h>
class FBXDocument : public GLTFDocument {
GDCLASS(FBXDocument, GLTFDocument);
public:
enum {
TEXTURE_TYPE_GENERIC = 0,
TEXTURE_TYPE_NORMAL = 1,
};
static Transform3D _as_xform(const ufbx_matrix &p_mat);
static String _as_string(const ufbx_string &p_string);
static Vector3 _as_vec3(const ufbx_vec3 &p_vector);
static String _gen_unique_name(HashSet<String> &unique_names, const String &p_name);
public:
Error append_from_file(String p_path, Ref<GLTFState> p_state, uint32_t p_flags = 0, String p_base_path = String()) override;
Error append_from_buffer(PackedByteArray p_bytes, String p_base_path, Ref<GLTFState> p_state, uint32_t p_flags = 0) override;
Error append_from_scene(Node *p_node, Ref<GLTFState> p_state, uint32_t p_flags = 0) override;
Node *generate_scene(Ref<GLTFState> p_state, float p_bake_fps = 30.0f, bool p_trimming = false, bool p_remove_immutable_tracks = true) override;
PackedByteArray generate_buffer(Ref<GLTFState> p_state) override;
Error write_to_filesystem(Ref<GLTFState> p_state, const String &p_path) override;
protected:
static void _bind_methods();
private:
String _get_texture_path(const String &p_base_directory, const String &p_source_file_path) const;
void _process_uv_set(PackedVector2Array &uv_array);
void _zero_unused_elements(Vector<float> &cur_custom, int start, int end, int num_channels);
Error _parse_scenes(Ref<FBXState> p_state);
Error _parse_nodes(Ref<FBXState> p_state);
String _sanitize_animation_name(const String &p_name);
String _gen_unique_animation_name(Ref<FBXState> p_state, const String &p_name);
Ref<Texture2D> _get_texture(Ref<FBXState> p_state,
const GLTFTextureIndex p_texture, int p_texture_type);
Error _parse_meshes(Ref<FBXState> p_state);
Ref<Image> _parse_image_bytes_into_image(Ref<FBXState> p_state, const Vector<uint8_t> &p_bytes, const String &p_filename, int p_index);
GLTFImageIndex _parse_image_save_image(Ref<FBXState> p_state, const Vector<uint8_t> &p_bytes, const String &p_file_extension, int p_index, Ref<Image> p_image);
Error _parse_images(Ref<FBXState> p_state, const String &p_base_path);
Error _parse_materials(Ref<FBXState> p_state);
Error _parse_skins(Ref<FBXState> p_state);
Error _parse_animations(Ref<FBXState> p_state);
BoneAttachment3D *_generate_bone_attachment(Ref<FBXState> p_state,
Skeleton3D *p_skeleton,
const GLTFNodeIndex p_node_index,
const GLTFNodeIndex p_bone_index);
ImporterMeshInstance3D *_generate_mesh_instance(Ref<FBXState> p_state, const GLTFNodeIndex p_node_index);
Camera3D *_generate_camera(Ref<FBXState> p_state, const GLTFNodeIndex p_node_index);
Light3D *_generate_light(Ref<FBXState> p_state, const GLTFNodeIndex p_node_index);
Node3D *_generate_spatial(Ref<FBXState> p_state, const GLTFNodeIndex p_node_index);
void _assign_node_names(Ref<FBXState> p_state);
Error _parse_cameras(Ref<FBXState> p_state);
Error _parse_lights(Ref<FBXState> p_state);
public:
Error _parse_fbx_state(Ref<FBXState> p_state, const String &p_search_path);
void _process_mesh_instances(Ref<FBXState> p_state, Node *p_scene_root);
void _generate_scene_node(Ref<FBXState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root);
void _generate_skeleton_bone_node(Ref<FBXState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root);
void _import_animation(Ref<FBXState> p_state, AnimationPlayer *p_animation_player,
const GLTFAnimationIndex p_index, const bool p_trimming, const bool p_remove_immutable_tracks);
Error _parse(Ref<FBXState> p_state, String p_path, Ref<FileAccess> p_file);
};
#endif // FBX_DOCUMENT_H

View file

@ -0,0 +1,46 @@
/**************************************************************************/
/* fbx_state.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 "fbx_state.h"
void FBXState::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_allow_geometry_helper_nodes"), &FBXState::get_allow_geometry_helper_nodes);
ClassDB::bind_method(D_METHOD("set_allow_geometry_helper_nodes", "allow"), &FBXState::set_allow_geometry_helper_nodes);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_geometry_helper_nodes"), "set_allow_geometry_helper_nodes", "get_allow_geometry_helper_nodes");
}
bool FBXState::get_allow_geometry_helper_nodes() {
return allow_geometry_helper_nodes;
}
void FBXState::set_allow_geometry_helper_nodes(bool p_allow_geometry_helper_nodes) {
allow_geometry_helper_nodes = p_allow_geometry_helper_nodes;
}

View file

@ -0,0 +1,69 @@
/**************************************************************************/
/* fbx_state.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 FBX_STATE_H
#define FBX_STATE_H
#include "modules/gltf/gltf_defines.h"
#include "modules/gltf/gltf_state.h"
#include "modules/gltf/structures/gltf_skeleton.h"
#include "modules/gltf/structures/gltf_skin.h"
#include "modules/gltf/structures/gltf_texture.h"
#include <ufbx.h>
class FBXState : public GLTFState {
GDCLASS(FBXState, GLTFState);
friend class FBXDocument;
friend class SkinTool;
friend class GLTFSkin;
// Smart pointer that holds the loaded scene.
ufbx_unique_ptr<ufbx_scene> scene;
bool allow_geometry_helper_nodes = false;
HashMap<uint64_t, Image::AlphaMode> alpha_mode_cache;
HashMap<Pair<uint64_t, uint64_t>, GLTFTextureIndex, PairHash<uint64_t, uint64_t>> albedo_transparency_textures;
Vector<GLTFSkinIndex> skin_indices;
Vector<GLTFSkinIndex> original_skin_indices;
HashMap<ObjectID, GLTFSkeletonIndex> skeleton3d_to_fbx_skeleton;
HashMap<ObjectID, HashMap<ObjectID, GLTFSkinIndex>> skin_and_skeleton3d_to_fbx_skin;
HashSet<String> unique_mesh_names; // Not in GLTFState because GLTFState prefixes mesh names with the scene name (or _)
protected:
static void _bind_methods();
public:
bool get_allow_geometry_helper_nodes();
void set_allow_geometry_helper_nodes(bool p_allow_geometry_helper_nodes);
};
#endif // FBX_STATE_H

View file

@ -0,0 +1,88 @@
/**************************************************************************/
/* register_types.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 "register_types.h"
#include "fbx_document.h"
#ifdef TOOLS_ENABLED
#include "editor/editor_scene_importer_fbx2gltf.h"
#include "editor/editor_scene_importer_ufbx.h"
#include "core/config/project_settings.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
static void _editor_init() {
Ref<EditorSceneFormatImporterUFBX> import_fbx;
import_fbx.instantiate();
ResourceImporterScene::add_scene_importer(import_fbx);
bool fbx2gltf_enabled = GLOBAL_GET("filesystem/import/fbx2gltf/enabled");
if (fbx2gltf_enabled) {
Ref<EditorSceneFormatImporterFBX2GLTF> importer;
importer.instantiate();
ResourceImporterScene::add_scene_importer(importer);
}
}
#endif // TOOLS_ENABLED
void initialize_fbx_module(ModuleInitializationLevel p_level) {
if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE) {
GDREGISTER_CLASS(FBXDocument);
GDREGISTER_CLASS(FBXState);
}
#ifdef TOOLS_ENABLED
if (p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) {
// Editor-specific API.
ClassDB::APIType prev_api = ClassDB::get_current_api();
ClassDB::set_current_api(ClassDB::API_EDITOR);
GDREGISTER_CLASS(EditorSceneFormatImporterUFBX);
GLOBAL_DEF_RST_BASIC("filesystem/import/fbx2gltf/enabled", true);
GDREGISTER_CLASS(EditorSceneFormatImporterFBX2GLTF);
GLOBAL_DEF_RST("filesystem/import/fbx2gltf/enabled.android", false);
GLOBAL_DEF_RST("filesystem/import/fbx2gltf/enabled.web", false);
ClassDB::set_current_api(prev_api);
EditorNode::add_init_callback(_editor_init);
}
#endif // TOOLS_ENABLED
}
void uninitialize_fbx_module(ModuleInitializationLevel p_level) {
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
return;
}
// TODO: 20240118 // fire
// FBXDocument::unregister_all_gltf_document_extensions();
}

View file

@ -0,0 +1,39 @@
/**************************************************************************/
/* register_types.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 FBX_REGISTER_TYPES_H
#define FBX_REGISTER_TYPES_H
#include "modules/register_module_types.h"
void initialize_fbx_module(ModuleInitializationLevel p_level);
void uninitialize_fbx_module(ModuleInitializationLevel p_level);
#endif // FBX_REGISTER_TYPES_H