Skip to content
Open
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
2 changes: 1 addition & 1 deletion .github/workflows/all_builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ env:
# TODO: change this back to godotengine/godot and target master when #109685 and #109475 are merged
GODOT_REPOSITORY: nikitalita/godot
# Change the README too
GODOT_MAIN_SYNC_REF: gdre-wb-df6235838b6
GODOT_MAIN_SYNC_REF: gdre-wb-f964fa714f5
SCONSFLAGS: verbose=yes warnings=all werror=no module_text_server_fb_enabled=yes minizip=yes deprecated=yes angle=yes accesskit=no
SCONSFLAGS_TEMPLATE: disable_path_overrides=no no_editor_splash=yes module_camera_enabled=no module_mobile_vr_enabled=no module_upnp_enabled=no module_websocket_enabled=no module_csg_enabled=yes module_gridmap_enabled=yes use_static_cpp=yes builtin_freetype=yes builtin_libpng=yes builtin_zlib=yes builtin_libwebp=yes builtin_libvorbis=yes builtin_libogg=yes disable_3d=no
SCONS_CACHE_MSVC_CONFIG: true
Expand Down
3 changes: 1 addition & 2 deletions .scripts/rebase_godot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,9 @@ BRANCHES_TO_MERGE=(
gltf-fix-skeleton-bone
gltf-fix-double-precision
gltf-fix-vertex-colors
ensure-bptc-textures
fix-v3-meshes
fix-clearcoat-gloss
fix-blend-export
gltf-mutex-all-document-extensions
)

# set fail on error
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ During SCons configure, the module auto-applies the patches under `modules/gdsde

### Requirements

[Our fork of godot](https://github.com/nikitalita/godot) @ branch `gdre-wb-df6235838b6`
[Our fork of godot](https://github.com/nikitalita/godot) @ branch `gdre-wb-f964fa714f5`

- Support for building on 3.x has been dropped and no new features are being pushed
- Godot RE Tools still retains the ability to decompile 3.x and 2.x projects, however.
Expand Down
16 changes: 16 additions & 0 deletions compat/config_file_compat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,22 @@ Vector<String> ConfigFileCompat::get_section_keys(const String &p_section) const
return keys;
}

Vector<Pair<String, Variant>> ConfigFileCompat::get_section_keys_with_values_beginning_with(const String &p_section, const String &p_prefix) const {
Vector<Pair<String, Variant>> keys;
ERR_FAIL_COND_V_MSG(!values.has(p_section), keys, vformat("Cannot get keys from nonexistent section \"%s\".", p_section));

const HashMap<String, Variant> &keys_map = values[p_section];
keys.reserve(keys_map.size());

for (const KeyValue<String, Variant> &E : keys_map) {
if (E.key.begins_with(p_prefix)) {
keys.push_back({ E.key, E.value });
}
}

return keys;
}

void ConfigFileCompat::erase_section(const String &p_section) {
ERR_FAIL_COND_MSG(!values.has(p_section), vformat("Cannot erase nonexistent section \"%s\".", p_section));
values.erase(p_section);
Expand Down
1 change: 1 addition & 0 deletions compat/config_file_compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class ConfigFileCompat : public RefCounted {

Vector<String> get_sections() const;
Vector<String> get_section_keys(const String &p_section) const;
Vector<Pair<String, Variant>> get_section_keys_with_values_beginning_with(const String &p_section, const String &p_key_prefix) const;

void erase_section(const String &p_section);
void erase_section_key(const String &p_section, const String &p_key);
Expand Down
9 changes: 6 additions & 3 deletions docs/gdre_custom_pack_source.gd
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
class_name GDRECustomPackSource
class_name GDREStandardPackSource
extends PackSourceCustom

# This script re-implements the standard pack source logic for Godot PCK files.
# Use this as a base for your own custom pack source logic.

# Godot's packed file magic header ("GDPC" in ASCII, little-endian).
# Godot's packed file magic header ("GDPC" in ASCII, stored as little-endian in the file).
const PACK_HEADER_MAGIC: int = 0x43504447
# 'G', 'D', 'P', 'C' in ASCII.
var PACK_HEADER_MAGIC_BYTES: PackedByteArray = PackedByteArray([0x47, 0x44, 0x50, 0x43])
const PACK_FORMAT_VERSION_V2: int = 2
const PACK_FORMAT_VERSION_V3: int = 3
Expand All @@ -26,7 +29,7 @@ func open_encrypted_file(base: FileAccess, key: PackedByteArray) -> FileAccess:
return FileAccessEncryptedCustom.create_and_parse_non_custom(base, key, FileAccessEncryptedCustom.MODE_READ, false)

func _try_open_pack(pck_path: String, p_replace_files: bool, p_offset: int, p_decryption_key: PackedByteArray) -> bool:
var ext: String = p_path.get_extension().to_lower()
var ext: String = pck_path.get_extension().to_lower()
if ext == "apk" or ext == "zip":
return false

Expand Down
52 changes: 41 additions & 11 deletions exporters/scene_exporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1875,7 +1875,7 @@
}
if (meshes.size() > 1) {
SurfaceTool surface_tool;
for (size_t i = 0; i < meshes.size(); i++) {

Check warning on line 1878 in exporters/scene_exporter.cpp

View workflow job for this annotation

GitHub Actions / Windows Template Release

'<': signed/unsigned mismatch

Check warning on line 1878 in exporters/scene_exporter.cpp

View workflow job for this annotation

GitHub Actions / Windows Editor

'<': signed/unsigned mismatch
for (size_t j = 0; j < meshes[i]->get_surface_count(); j++) {
if (i == 0 && j == 0) {
surface_tool.create_from(meshes[i], j);
Expand Down Expand Up @@ -2849,7 +2849,7 @@
return root;
}

Error GLBExporterInstance::_load_scene_and_deps(Ref<PackedScene> &r_scene) {
Error GLBExporterInstance::_load_scene_and_deps(Ref<Resource> &r_scene) {
MeshInstance3D::upgrading_skeleton_compat = true;
err = _load_deps();
if (err != OK) {
Expand All @@ -2858,23 +2858,23 @@
return _load_scene(r_scene);
}

Error GLBExporterInstance::_load_scene(Ref<PackedScene> &r_scene) {
Error GLBExporterInstance::_load_scene(Ref<Resource> &r_scene) {
auto mode_type = ResourceCompatLoader::get_default_load_type();
// loading older scenes will spam warnings about deprecated features
#ifndef DEBUG_ENABLED
if (ver_major <= 3) {
_silence_errors(true);
}
#endif
std::optional<Ref<PackedScene>> result;
std::optional<Ref<Resource>> result;
// For some reason, scenes with meshes fail to load without the load done by ResourceLoader::load, possibly due to notification shenanigans.
if (ResourceCompatLoader::is_globally_available()) {
result = TaskManager::get_singleton()->dispatch_to_main_thread((std::function<Ref<PackedScene>()>)[&]() -> Ref<PackedScene> {
return ResourceLoader::load(source_path, "PackedScene", ResourceFormatLoader::CACHE_MODE_REUSE, &err);
result = TaskManager::get_singleton()->dispatch_to_main_thread((std::function<Ref<Resource>()>)[&]() -> Ref<Resource> {
return ResourceLoader::load(source_path, "", ResourceFormatLoader::CACHE_MODE_REUSE, &err);
});
} else {
result = TaskManager::get_singleton()->dispatch_to_main_thread((std::function<Ref<PackedScene>()>)[&]() -> Ref<PackedScene> {
return ResourceCompatLoader::custom_load(source_path, "PackedScene", mode_type, &err, using_threaded_load(), ResourceFormatLoader::CACHE_MODE_REUSE);
result = TaskManager::get_singleton()->dispatch_to_main_thread((std::function<Ref<Resource>()>)[&]() -> Ref<Resource> {
return ResourceCompatLoader::custom_load(source_path, "", mode_type, &err, using_threaded_load(), ResourceFormatLoader::CACHE_MODE_REUSE);
});
}
if (!result.has_value()) {
Expand Down Expand Up @@ -3294,6 +3294,18 @@
return _check_unsupported(ver_major, is_text_output());
}

Error create_packed_scene_from_mesh(const Ref<Mesh> &mesh, Ref<PackedScene> &scene) {
ERR_FAIL_COND_V_MSG(mesh.is_null(), ERR_INVALID_PARAMETER, "Mesh is null");
return TaskManager::get_singleton()->dispatch_to_main_thread((std::function<Error()>)[&]() -> Error {
MeshInstance3D *root = memnew(MeshInstance3D);
root->set_mesh(mesh);
scene = Ref<PackedScene>(memnew(PackedScene));
scene->pack(root);
return OK;
})
.value_or(ERR_SKIP);
}

// scene loading and scene instancing has to be done on the main thread to avoid deadlocks and crashes
bool batch_preload() {
GDRELogger::clear_error_queues();
Expand All @@ -3318,13 +3330,31 @@

err = gdre::ensure_dir(p_dest_path.get_base_dir());
report->set_error(err);
ERR_FAIL_COND_V_MSG(err, false, "Failed to ensure directory " + p_dest_path.get_base_dir());
if (err) {
after_preload();
ERR_FAIL_V_MSG(false, "Failed to ensure directory " + p_dest_path.get_base_dir());
}
{
Ref<PackedScene> scene;
err = instance._load_scene_and_deps(scene);
if (scene.is_null() && err == OK) {
String resource_type = report->get_import_info()->get_type();
bool is_mesh = false;
if (resource_type != "PackedScene") {
if (resource_type != "Mesh" && !ClassDB::is_parent_class(resource_type, "Mesh")) {
after_preload();
ERR_FAIL_V_MSG(false, "Unsupported resource type: " + resource_type);
}
is_mesh = true;
}
Ref<Resource> resource;
err = instance._load_scene_and_deps(resource);
if (resource.is_null() && err == OK) {
err = ERR_CANT_ACQUIRE_RESOURCE;
}

Ref<PackedScene> scene = resource;
if (err == OK && scene.is_null() && is_mesh) {
err = create_packed_scene_from_mesh(resource, scene);
}

if (err != OK) {
report->set_error(err);
after_preload();
Expand Down Expand Up @@ -3602,7 +3632,7 @@
Vector<String> GLBExporterInstance::_get_logged_error_messages() {
auto errors = supports_multithread() ? GDRELogger::get_thread_errors() : GDRELogger::get_errors();
Vector<String> ret;
for (auto &err : errors) {

Check warning on line 3635 in exporters/scene_exporter.cpp

View workflow job for this annotation

GitHub Actions / Windows Template Release

declaration of 'err' hides class member

Check warning on line 3635 in exporters/scene_exporter.cpp

View workflow job for this annotation

GitHub Actions / Windows Editor

declaration of 'err' hides class member
String lstripped = err.strip_edges(true, false);
if (!lstripped.begins_with("GDScript backtrace")) {
ret.push_back(err.strip_edges(false, true));
Expand Down
4 changes: 2 additions & 2 deletions exporters/scene_exporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,8 @@ class GLBExporterInstance {
Dictionary _get_default_subresource_options();
Error _check_model_can_load(const String &p_dest_path);
Error _load_deps();
Error _load_scene_and_deps(Ref<PackedScene> &r_scene);
Error _load_scene(Ref<PackedScene> &r_scene);
Error _load_scene_and_deps(Ref<Resource> &r_scene);
Error _load_scene(Ref<Resource> &r_scene);
void recompute_animation_tracks_for_library(AnimationPlayer *p_player, const Ref<AnimationLibrary> &p_anim_lib, const LocalVector<StringName> &p_anim_names);
void convert_animation_tracks_to_v4_for_player(AnimationPlayer *p_player);

Expand Down
13 changes: 9 additions & 4 deletions register_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "gui/texture_previewer.h"
#include "modules/regex/regex.h"
#include "modules/register_module_types.h"
#include "servers/rendering/rendering_server.h"
#include "utility/app_version_getter.h"
#include "utility/file_access_gdre.h"
#include "utility/file_access_patched_gdre.h"
Expand Down Expand Up @@ -618,16 +619,20 @@ void initialize_gdsdecomp_module(ModuleInitializationLevel p_level) {
// Register ICO image loader
ico_loader.instantiate();
ImageLoader::add_image_format_loader(ico_loader);
TextureLayeredPreviewer::init_shaders();
TexturePreviewer::init_shaders();
if (RenderingServer::get_singleton()) {
TextureLayeredPreviewer::init_shaders();
TexturePreviewer::init_shaders();
}
}

void uninitialize_gdsdecomp_module(ModuleInitializationLevel p_level) {
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
return;
}
TextureLayeredPreviewer::finish_shaders();
TexturePreviewer::finish_shaders();
if (RenderingServer::get_singleton()) {
TextureLayeredPreviewer::finish_shaders();
TexturePreviewer::finish_shaders();
}
if (ico_loader.is_valid()) {
ImageLoader::remove_image_format_loader(ico_loader);
ico_loader.unref();
Expand Down
4 changes: 4 additions & 0 deletions standalone/gdre_config_dialog.gd
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ func make_button_label(text: String) -> Label:


func set_setting_value(setting: GDREConfigSetting, value: Variant):
if setting.get_type() == TYPE_INT:
value = int(value)
elif setting.get_type() == TYPE_FLOAT:
value = float(value)
setting_value_map[setting] = value

func setting_callback(setting: GDREConfigSetting, value: Variant, control: Control):
Expand Down
72 changes: 70 additions & 2 deletions standalone/gdre_recover.gd
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ func _get_all_files(files: PackedStringArray) -> PackedStringArray:

const DIR_STRUCTURE_OPTION_NAME = "Directory Structure"
const EXPORT_SCENE_OPTION_NAME = "Export Scenes as"
const EXPORT_MESH_OPTION_NAME = "Export Meshes as"

enum DirStructure {
FLAT,
Expand All @@ -96,6 +97,14 @@ enum ExportSceneType {
GLTF
}

enum ExportMeshType {
AUTO,
TRES,
OBJ,
GLB,
GLTF
}

const DIR_STRUCTURE_NAMES: PackedStringArray = [
"Flat",
"Relative Hierarchical",
Expand All @@ -109,6 +118,14 @@ const EXPORT_SCENE_TYPE_NAMES: PackedStringArray = [
"GLTF",
]

const EXPORT_MESH_TYPE_NAMES: PackedStringArray = [
"Auto",
"tres",
"OBJ",
"GLB",
"GLTF",
]

func get_output_file_name(src: String, output_folder: String, dir_structure_option: DirStructure, new_ext: String = "", rel_base: String = "") -> String:
var new_name = ""
if dir_structure_option == DirStructure.FLAT:
Expand Down Expand Up @@ -150,6 +167,44 @@ func _export_scene(file: String, output_dir: String, dir_structure: DirStructure
report.error = OK
return report

# TODO: A more generic way to export resources, stop copying all this code around
func _export_mesh(file: String, output_dir: String, dir_structure: DirStructure, rel_base: String, export_type: ExportMeshType) -> ExportReport:
var source_file = file
var iinfo = GDRESettings.get_import_info_by_dest(file)
if iinfo:
source_file = iinfo.source_file

var ext = source_file.get_extension().to_lower()

if export_type == ExportMeshType.GLB:
ext = "glb"
elif export_type == ExportMeshType.GLTF:
ext = "gltf"
elif export_type == ExportMeshType.OBJ:
ext = "obj"
elif export_type == ExportMeshType.TRES:
ext = "tres"
else: # AUTO
if not is_instance_valid(iinfo):
ext = "tres"

var report: ExportReport = ExportReport.new()
var export_dest = get_output_file_name(source_file, output_dir, dir_structure, ext, rel_base)
if ext == "tres":
# just use bin to text
report.error = ResourceCompatLoader.to_text(file, export_dest)
return report

if export_type == ExportMeshType.OBJ:
report.error = ObjExporter.export_file_with_options(export_dest, file, {})
else:
report = SceneExporter.export_file_with_options(export_dest, file, {
"Exporter/Scene/GLTF/replace_shader_materials": true,
})
if (report.error == ERR_BUG or report.error == ERR_PRINTER_ON_FIRE or report.error == ERR_DATABASE_CANT_READ):
report.error = OK
return report


func get_log_error_string(errs: PackedStringArray) -> String:
return "\n".join(GDRECommon.filter_error_backtraces(errs))
Expand All @@ -167,7 +222,7 @@ func convert_pcfg_to_text(path: String, output_dir: String) -> Array:
return [err, text_file]
return [loader.save_cfb(output_dir, ver_major, ver_minor), text_file]

func _export_files(files: PackedStringArray, output_dir: String, dir_structure: DirStructure, rel_base: String, export_glb: ExportSceneType) -> PackedStringArray:
func _export_files(files: PackedStringArray, output_dir: String, dir_structure: DirStructure, rel_base: String, export_glb: ExportSceneType, export_mesh: ExportMeshType) -> PackedStringArray:
var errs: PackedStringArray = []
files = _get_all_files(files)

Expand Down Expand Up @@ -201,6 +256,12 @@ func _export_files(files: PackedStringArray, output_dir: String, dir_structure:
errs.append("Exporting cancelled: " + file + "\n" + report.message + "\n" + get_log_error_string(report.get_error_messages()))
break
errs.append("Failed to export resource: " + file + "\n" + report.message + "\n" + get_log_error_string(report.get_error_messages()))
if file_ext == "mesh" or (_ret and _ret.get_compat_type().contains("Mesh")) and export_mesh != ExportMeshType.AUTO:
var report: ExportReport = _export_mesh(file, output_dir, dir_structure, rel_base, export_mesh)
if not report:
errs.append("Failed to export resource: " + file + get_log_error_string(GDRESettings.get_errors()))
elif report.error != OK and report.error != ERR_PRINTER_ON_FIRE:
errs.append("Failed to export resource: " + file + "\n" + report.message + "\n" + get_log_error_string(report.get_error_messages()))
elif _ret:
var iinfo: ImportInfo = ImportInfo.copy(_ret)
iinfo.export_dest = get_output_file_name(iinfo.source_file, "res://", dir_structure, iinfo.source_file.get_extension().to_lower(), rel_base)
Expand Down Expand Up @@ -263,8 +324,9 @@ func _do_export(output_dir: String, export_preview_visible: bool):
var options = %ExportResDirDialog.get_selected_options()
var dir_structure = options.get(DIR_STRUCTURE_OPTION_NAME, DirStructure.RELATIVE_HIERARCHICAL)
var export_glb: ExportSceneType = options.get(EXPORT_SCENE_OPTION_NAME, int(ExportSceneType.AUTO))
var export_mesh: ExportMeshType = options.get(EXPORT_MESH_OPTION_NAME, int(ExportMeshType.AUTO))

errs = _export_files(files, output_dir, dir_structure, rel_base, export_glb)
errs = _export_files(files, output_dir, dir_structure, rel_base, export_glb, export_mesh)
if export_preview_visible:
%GdreResourcePreview.set_main_view_visible(true)

Expand Down Expand Up @@ -371,6 +433,12 @@ func _set_file_dialog_options(file_dialog: FileDialog, default_dir_structure: Di
if not include_scene:
return
var include_glb = GDRESettings.get_ver_major() >= SceneExporter.get_minimum_godot_ver_supported()
var mesh_default = options.get(EXPORT_MESH_OPTION_NAME, int(ExportMeshType.AUTO))
var mesh_opts = EXPORT_MESH_TYPE_NAMES.duplicate()
if not include_glb:
mesh_opts.remove_at(int(ExportMeshType.GLTF))
mesh_opts.remove_at(int(ExportMeshType.GLB))
file_dialog.add_option(EXPORT_MESH_OPTION_NAME, mesh_opts, mesh_default)
var scene_default = options.get(EXPORT_SCENE_OPTION_NAME, int(ExportSceneType.AUTO))
#file_dialog.set_option_default(0, int(default_dir_structure))
var glb_opts = EXPORT_SCENE_TYPE_NAMES.duplicate()
Expand Down
Loading
Loading