diff options
79 files changed, 1847 insertions, 1484 deletions
diff --git a/.github/workflows/android_builds.yml b/.github/workflows/android_builds.yml index 63930aa9e2..a618b69e30 100644 --- a/.github/workflows/android_builds.yml +++ b/.github/workflows/android_builds.yml @@ -39,6 +39,7 @@ jobs: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}} ${{github.job}}-${{env.GODOT_BASE_BRANCH}} + continue-on-error: true # Use python 3.x release (works cross platform) - name: Set up Python 3.x diff --git a/.github/workflows/ios_builds.yml b/.github/workflows/ios_builds.yml index c4da3cb683..6f5ffcf42f 100644 --- a/.github/workflows/ios_builds.yml +++ b/.github/workflows/ios_builds.yml @@ -26,6 +26,7 @@ jobs: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}} ${{github.job}}-${{env.GODOT_BASE_BRANCH}} + continue-on-error: true # Use python 3.x release (works cross platform) - name: Set up Python 3.x diff --git a/.github/workflows/javascript_builds.yml b/.github/workflows/javascript_builds.yml index f88d14fbe9..5124197d3d 100644 --- a/.github/workflows/javascript_builds.yml +++ b/.github/workflows/javascript_builds.yml @@ -35,6 +35,7 @@ jobs: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}} ${{github.job}}-${{env.GODOT_BASE_BRANCH}} + continue-on-error: true # Additional cache for Emscripten generated system libraries - name: Load Emscripten cache diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index 679362d749..e2b9fa8a7b 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -39,6 +39,7 @@ jobs: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}} ${{github.job}}-${{env.GODOT_BASE_BRANCH}} + continue-on-error: true # Use python 3.x release (works cross platform; best to keep self contained in it's own step) - name: Set up Python 3.x @@ -125,6 +126,7 @@ jobs: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}} ${{github.job}}-${{env.GODOT_BASE_BRANCH}} + continue-on-error: true # Use python 3.x release (works cross platform; best to keep self contained in it's own step) - name: Set up Python 3.x @@ -215,6 +217,7 @@ jobs: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}} ${{github.job}}-${{env.GODOT_BASE_BRANCH}} + continue-on-error: true # Use python 3.x release (works cross platform) - name: Set up Python 3.x diff --git a/.github/workflows/macos_builds.yml b/.github/workflows/macos_builds.yml index a15ab92052..abc561eaa9 100644 --- a/.github/workflows/macos_builds.yml +++ b/.github/workflows/macos_builds.yml @@ -27,6 +27,7 @@ jobs: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}} ${{github.job}}-${{env.GODOT_BASE_BRANCH}} + continue-on-error: true # Use python 3.x release (works cross platform; best to keep self contained in it's own step) - name: Set up Python 3.x @@ -82,6 +83,7 @@ jobs: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}} ${{github.job}}-${{env.GODOT_BASE_BRANCH}} + continue-on-error: true # Use python 3.x release (works cross platform) - name: Set up Python 3.x diff --git a/.github/workflows/windows_builds.yml b/.github/workflows/windows_builds.yml index d1db449ab0..1f9e3ac5e3 100644 --- a/.github/workflows/windows_builds.yml +++ b/.github/workflows/windows_builds.yml @@ -32,6 +32,7 @@ jobs: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}} ${{github.job}}-${{env.GODOT_BASE_BRANCH}} + continue-on-error: true # Use python 3.x release (works cross platform; best to keep self contained in it's own step) - name: Set up Python 3.x @@ -88,6 +89,7 @@ jobs: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}} ${{github.job}}-${{env.GODOT_BASE_BRANCH}} + continue-on-error: true # Use python 3.x release (works cross platform) - name: Set up Python 3.x diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 7a2e6765b8..efb4b84716 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -41,39 +41,41 @@ #include "core/os/keyboard.h" #include "core/os/os.h" -////// _ResourceLoader ////// +namespace core_bind { -_ResourceLoader *_ResourceLoader::singleton = nullptr; +////// ResourceLoader ////// -Error _ResourceLoader::load_threaded_request(const String &p_path, const String &p_type_hint, bool p_use_sub_threads) { - return ResourceLoader::load_threaded_request(p_path, p_type_hint, p_use_sub_threads); +ResourceLoader *ResourceLoader::singleton = nullptr; + +Error ResourceLoader::load_threaded_request(const String &p_path, const String &p_type_hint, bool p_use_sub_threads) { + return ::ResourceLoader::load_threaded_request(p_path, p_type_hint, p_use_sub_threads); } -_ResourceLoader::ThreadLoadStatus _ResourceLoader::load_threaded_get_status(const String &p_path, Array r_progress) { +ResourceLoader::ThreadLoadStatus ResourceLoader::load_threaded_get_status(const String &p_path, Array r_progress) { float progress = 0; - ResourceLoader::ThreadLoadStatus tls = ResourceLoader::load_threaded_get_status(p_path, &progress); + ::ResourceLoader::ThreadLoadStatus tls = ::ResourceLoader::load_threaded_get_status(p_path, &progress); r_progress.resize(1); r_progress[0] = progress; return (ThreadLoadStatus)tls; } -RES _ResourceLoader::load_threaded_get(const String &p_path) { +RES ResourceLoader::load_threaded_get(const String &p_path) { Error error; - RES res = ResourceLoader::load_threaded_get(p_path, &error); + RES res = ::ResourceLoader::load_threaded_get(p_path, &error); return res; } -RES _ResourceLoader::load(const String &p_path, const String &p_type_hint, CacheMode p_cache_mode) { +RES ResourceLoader::load(const String &p_path, const String &p_type_hint, CacheMode p_cache_mode) { Error err = OK; - RES ret = ResourceLoader::load(p_path, p_type_hint, ResourceFormatLoader::CacheMode(p_cache_mode), &err); + RES ret = ::ResourceLoader::load(p_path, p_type_hint, ResourceFormatLoader::CacheMode(p_cache_mode), &err); ERR_FAIL_COND_V_MSG(err != OK, ret, "Error loading resource: '" + p_path + "'."); return ret; } -Vector<String> _ResourceLoader::get_recognized_extensions_for_type(const String &p_type) { +Vector<String> ResourceLoader::get_recognized_extensions_for_type(const String &p_type) { List<String> exts; - ResourceLoader::get_recognized_extensions_for_type(p_type, &exts); + ::ResourceLoader::get_recognized_extensions_for_type(p_type, &exts); Vector<String> ret; for (const String &E : exts) { ret.push_back(E); @@ -82,13 +84,13 @@ Vector<String> _ResourceLoader::get_recognized_extensions_for_type(const String return ret; } -void _ResourceLoader::set_abort_on_missing_resources(bool p_abort) { - ResourceLoader::set_abort_on_missing_resources(p_abort); +void ResourceLoader::set_abort_on_missing_resources(bool p_abort) { + ::ResourceLoader::set_abort_on_missing_resources(p_abort); } -PackedStringArray _ResourceLoader::get_dependencies(const String &p_path) { +PackedStringArray ResourceLoader::get_dependencies(const String &p_path) { List<String> deps; - ResourceLoader::get_dependencies(p_path, &deps); + ::ResourceLoader::get_dependencies(p_path, &deps); PackedStringArray ret; for (const String &E : deps) { @@ -98,31 +100,31 @@ PackedStringArray _ResourceLoader::get_dependencies(const String &p_path) { return ret; } -bool _ResourceLoader::has_cached(const String &p_path) { +bool ResourceLoader::has_cached(const String &p_path) { String local_path = ProjectSettings::get_singleton()->localize_path(p_path); return ResourceCache::has(local_path); } -bool _ResourceLoader::exists(const String &p_path, const String &p_type_hint) { - return ResourceLoader::exists(p_path, p_type_hint); +bool ResourceLoader::exists(const String &p_path, const String &p_type_hint) { + return ::ResourceLoader::exists(p_path, p_type_hint); } -ResourceUID::ID _ResourceLoader::get_resource_uid(const String &p_path) { - return ResourceLoader::get_resource_uid(p_path); +ResourceUID::ID ResourceLoader::get_resource_uid(const String &p_path) { + return ::ResourceLoader::get_resource_uid(p_path); } -void _ResourceLoader::_bind_methods() { - ClassDB::bind_method(D_METHOD("load_threaded_request", "path", "type_hint", "use_sub_threads"), &_ResourceLoader::load_threaded_request, DEFVAL(""), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("load_threaded_get_status", "path", "progress"), &_ResourceLoader::load_threaded_get_status, DEFVAL(Array())); - ClassDB::bind_method(D_METHOD("load_threaded_get", "path"), &_ResourceLoader::load_threaded_get); +void ResourceLoader::_bind_methods() { + ClassDB::bind_method(D_METHOD("load_threaded_request", "path", "type_hint", "use_sub_threads"), &ResourceLoader::load_threaded_request, DEFVAL(""), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("load_threaded_get_status", "path", "progress"), &ResourceLoader::load_threaded_get_status, DEFVAL(Array())); + ClassDB::bind_method(D_METHOD("load_threaded_get", "path"), &ResourceLoader::load_threaded_get); - ClassDB::bind_method(D_METHOD("load", "path", "type_hint", "cache_mode"), &_ResourceLoader::load, DEFVAL(""), DEFVAL(CACHE_MODE_REUSE)); - ClassDB::bind_method(D_METHOD("get_recognized_extensions_for_type", "type"), &_ResourceLoader::get_recognized_extensions_for_type); - ClassDB::bind_method(D_METHOD("set_abort_on_missing_resources", "abort"), &_ResourceLoader::set_abort_on_missing_resources); - ClassDB::bind_method(D_METHOD("get_dependencies", "path"), &_ResourceLoader::get_dependencies); - ClassDB::bind_method(D_METHOD("has_cached", "path"), &_ResourceLoader::has_cached); - ClassDB::bind_method(D_METHOD("exists", "path", "type_hint"), &_ResourceLoader::exists, DEFVAL("")); - ClassDB::bind_method(D_METHOD("get_resource_uid", "path"), &_ResourceLoader::get_resource_uid); + ClassDB::bind_method(D_METHOD("load", "path", "type_hint", "cache_mode"), &ResourceLoader::load, DEFVAL(""), DEFVAL(CACHE_MODE_REUSE)); + ClassDB::bind_method(D_METHOD("get_recognized_extensions_for_type", "type"), &ResourceLoader::get_recognized_extensions_for_type); + ClassDB::bind_method(D_METHOD("set_abort_on_missing_resources", "abort"), &ResourceLoader::set_abort_on_missing_resources); + ClassDB::bind_method(D_METHOD("get_dependencies", "path"), &ResourceLoader::get_dependencies); + ClassDB::bind_method(D_METHOD("has_cached", "path"), &ResourceLoader::has_cached); + ClassDB::bind_method(D_METHOD("exists", "path", "type_hint"), &ResourceLoader::exists, DEFVAL("")); + ClassDB::bind_method(D_METHOD("get_resource_uid", "path"), &ResourceLoader::get_resource_uid); BIND_ENUM_CONSTANT(THREAD_LOAD_INVALID_RESOURCE); BIND_ENUM_CONSTANT(THREAD_LOAD_IN_PROGRESS); @@ -134,17 +136,17 @@ void _ResourceLoader::_bind_methods() { BIND_ENUM_CONSTANT(CACHE_MODE_REPLACE); } -////// _ResourceSaver ////// +////// ResourceSaver ////// -Error _ResourceSaver::save(const String &p_path, const RES &p_resource, SaverFlags p_flags) { +Error ResourceSaver::save(const String &p_path, const RES &p_resource, SaverFlags p_flags) { ERR_FAIL_COND_V_MSG(p_resource.is_null(), ERR_INVALID_PARAMETER, "Can't save empty resource to path '" + String(p_path) + "'."); - return ResourceSaver::save(p_path, p_resource, p_flags); + return ::ResourceSaver::save(p_path, p_resource, p_flags); } -Vector<String> _ResourceSaver::get_recognized_extensions(const RES &p_resource) { +Vector<String> ResourceSaver::get_recognized_extensions(const RES &p_resource) { ERR_FAIL_COND_V_MSG(p_resource.is_null(), Vector<String>(), "It's not a reference to a valid Resource object."); List<String> exts; - ResourceSaver::get_recognized_extensions(p_resource, &exts); + ::ResourceSaver::get_recognized_extensions(p_resource, &exts); Vector<String> ret; for (const String &E : exts) { ret.push_back(E); @@ -152,11 +154,11 @@ Vector<String> _ResourceSaver::get_recognized_extensions(const RES &p_resource) return ret; } -_ResourceSaver *_ResourceSaver::singleton = nullptr; +ResourceSaver *ResourceSaver::singleton = nullptr; -void _ResourceSaver::_bind_methods() { - ClassDB::bind_method(D_METHOD("save", "path", "resource", "flags"), &_ResourceSaver::save, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("get_recognized_extensions", "type"), &_ResourceSaver::get_recognized_extensions); +void ResourceSaver::_bind_methods() { + ClassDB::bind_method(D_METHOD("save", "path", "resource", "flags"), &ResourceSaver::save, DEFVAL(0)); + ClassDB::bind_method(D_METHOD("get_recognized_extensions", "type"), &ResourceSaver::get_recognized_extensions); BIND_ENUM_CONSTANT(FLAG_RELATIVE_PATHS); BIND_ENUM_CONSTANT(FLAG_BUNDLE_RESOURCES); @@ -167,65 +169,65 @@ void _ResourceSaver::_bind_methods() { BIND_ENUM_CONSTANT(FLAG_REPLACE_SUBRESOURCE_PATHS); } -////// _OS ////// +////// OS ////// -PackedStringArray _OS::get_connected_midi_inputs() { - return OS::get_singleton()->get_connected_midi_inputs(); +PackedStringArray OS::get_connected_midi_inputs() { + return ::OS::get_singleton()->get_connected_midi_inputs(); } -void _OS::open_midi_inputs() { - OS::get_singleton()->open_midi_inputs(); +void OS::open_midi_inputs() { + ::OS::get_singleton()->open_midi_inputs(); } -void _OS::close_midi_inputs() { - OS::get_singleton()->close_midi_inputs(); +void OS::close_midi_inputs() { + ::OS::get_singleton()->close_midi_inputs(); } -void _OS::set_use_file_access_save_and_swap(bool p_enable) { +void OS::set_use_file_access_save_and_swap(bool p_enable) { FileAccess::set_backup_save(p_enable); } -void _OS::set_low_processor_usage_mode(bool p_enabled) { - OS::get_singleton()->set_low_processor_usage_mode(p_enabled); +void OS::set_low_processor_usage_mode(bool p_enabled) { + ::OS::get_singleton()->set_low_processor_usage_mode(p_enabled); } -bool _OS::is_in_low_processor_usage_mode() const { - return OS::get_singleton()->is_in_low_processor_usage_mode(); +bool OS::is_in_low_processor_usage_mode() const { + return ::OS::get_singleton()->is_in_low_processor_usage_mode(); } -void _OS::set_low_processor_usage_mode_sleep_usec(int p_usec) { - OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(p_usec); +void OS::set_low_processor_usage_mode_sleep_usec(int p_usec) { + ::OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(p_usec); } -int _OS::get_low_processor_usage_mode_sleep_usec() const { - return OS::get_singleton()->get_low_processor_usage_mode_sleep_usec(); +int OS::get_low_processor_usage_mode_sleep_usec() const { + return ::OS::get_singleton()->get_low_processor_usage_mode_sleep_usec(); } -void _OS::alert(const String &p_alert, const String &p_title) { - OS::get_singleton()->alert(p_alert, p_title); +void OS::alert(const String &p_alert, const String &p_title) { + ::OS::get_singleton()->alert(p_alert, p_title); } -String _OS::get_executable_path() const { - return OS::get_singleton()->get_executable_path(); +String OS::get_executable_path() const { + return ::OS::get_singleton()->get_executable_path(); } -Error _OS::shell_open(String p_uri) { +Error OS::shell_open(String p_uri) { if (p_uri.begins_with("res://")) { WARN_PRINT("Attempting to open an URL with the \"res://\" protocol. Use `ProjectSettings.globalize_path()` to convert a Godot-specific path to a system path before opening it with `OS.shell_open()`."); } else if (p_uri.begins_with("user://")) { WARN_PRINT("Attempting to open an URL with the \"user://\" protocol. Use `ProjectSettings.globalize_path()` to convert a Godot-specific path to a system path before opening it with `OS.shell_open()`."); } - return OS::get_singleton()->shell_open(p_uri); + return ::OS::get_singleton()->shell_open(p_uri); } -int _OS::execute(const String &p_path, const Vector<String> &p_arguments, Array r_output, bool p_read_stderr) { +int OS::execute(const String &p_path, const Vector<String> &p_arguments, Array r_output, bool p_read_stderr) { List<String> args; for (int i = 0; i < p_arguments.size(); i++) { args.push_back(p_arguments[i]); } String pipe; int exitcode = 0; - Error err = OS::get_singleton()->execute(p_path, args, &pipe, &exitcode, p_read_stderr); + Error err = ::OS::get_singleton()->execute(p_path, args, &pipe, &exitcode, p_read_stderr); r_output.push_back(pipe); if (err != OK) { return -1; @@ -233,45 +235,45 @@ int _OS::execute(const String &p_path, const Vector<String> &p_arguments, Array return exitcode; } -int _OS::create_process(const String &p_path, const Vector<String> &p_arguments) { +int OS::create_process(const String &p_path, const Vector<String> &p_arguments) { List<String> args; for (int i = 0; i < p_arguments.size(); i++) { args.push_back(p_arguments[i]); } - OS::ProcessID pid = 0; - Error err = OS::get_singleton()->create_process(p_path, args, &pid); + ::OS::ProcessID pid = 0; + Error err = ::OS::get_singleton()->create_process(p_path, args, &pid); if (err != OK) { return -1; } return pid; } -Error _OS::kill(int p_pid) { - return OS::get_singleton()->kill(p_pid); +Error OS::kill(int p_pid) { + return ::OS::get_singleton()->kill(p_pid); } -int _OS::get_process_id() const { - return OS::get_singleton()->get_process_id(); +int OS::get_process_id() const { + return ::OS::get_singleton()->get_process_id(); } -bool _OS::has_environment(const String &p_var) const { - return OS::get_singleton()->has_environment(p_var); +bool OS::has_environment(const String &p_var) const { + return ::OS::get_singleton()->has_environment(p_var); } -String _OS::get_environment(const String &p_var) const { - return OS::get_singleton()->get_environment(p_var); +String OS::get_environment(const String &p_var) const { + return ::OS::get_singleton()->get_environment(p_var); } -bool _OS::set_environment(const String &p_var, const String &p_value) const { - return OS::get_singleton()->set_environment(p_var, p_value); +bool OS::set_environment(const String &p_var, const String &p_value) const { + return ::OS::get_singleton()->set_environment(p_var, p_value); } -String _OS::get_name() const { - return OS::get_singleton()->get_name(); +String OS::get_name() const { + return ::OS::get_singleton()->get_name(); } -Vector<String> _OS::get_cmdline_args() { - List<String> cmdline = OS::get_singleton()->get_cmdline_args(); +Vector<String> OS::get_cmdline_args() { + List<String> cmdline = ::OS::get_singleton()->get_cmdline_args(); Vector<String> cmdlinev; for (const String &E : cmdline) { cmdlinev.push_back(E); @@ -280,81 +282,81 @@ Vector<String> _OS::get_cmdline_args() { return cmdlinev; } -String _OS::get_locale() const { - return OS::get_singleton()->get_locale(); +String OS::get_locale() const { + return ::OS::get_singleton()->get_locale(); } -String _OS::get_model_name() const { - return OS::get_singleton()->get_model_name(); +String OS::get_model_name() const { + return ::OS::get_singleton()->get_model_name(); } -Error _OS::set_thread_name(const String &p_name) { - return Thread::set_name(p_name); +Error OS::set_thread_name(const String &p_name) { + return ::Thread::set_name(p_name); } -Thread::ID _OS::get_thread_caller_id() const { - return Thread::get_caller_id(); +::Thread::ID OS::get_thread_caller_id() const { + return ::Thread::get_caller_id(); }; -bool _OS::has_feature(const String &p_feature) const { - return OS::get_singleton()->has_feature(p_feature); +bool OS::has_feature(const String &p_feature) const { + return ::OS::get_singleton()->has_feature(p_feature); } -uint64_t _OS::get_static_memory_usage() const { - return OS::get_singleton()->get_static_memory_usage(); +uint64_t OS::get_static_memory_usage() const { + return ::OS::get_singleton()->get_static_memory_usage(); } -uint64_t _OS::get_static_memory_peak_usage() const { - return OS::get_singleton()->get_static_memory_peak_usage(); +uint64_t OS::get_static_memory_peak_usage() const { + return ::OS::get_singleton()->get_static_memory_peak_usage(); } /** This method uses a signed argument for better error reporting as it's used from the scripting API. */ -void _OS::delay_usec(int p_usec) const { +void OS::delay_usec(int p_usec) const { ERR_FAIL_COND_MSG( p_usec < 0, vformat("Can't sleep for %d microseconds. The delay provided must be greater than or equal to 0 microseconds.", p_usec)); - OS::get_singleton()->delay_usec(p_usec); + ::OS::get_singleton()->delay_usec(p_usec); } /** This method uses a signed argument for better error reporting as it's used from the scripting API. */ -void _OS::delay_msec(int p_msec) const { +void OS::delay_msec(int p_msec) const { ERR_FAIL_COND_MSG( p_msec < 0, vformat("Can't sleep for %d milliseconds. The delay provided must be greater than or equal to 0 milliseconds.", p_msec)); - OS::get_singleton()->delay_usec(int64_t(p_msec) * 1000); + ::OS::get_singleton()->delay_usec(int64_t(p_msec) * 1000); } -bool _OS::can_use_threads() const { - return OS::get_singleton()->can_use_threads(); +bool OS::can_use_threads() const { + return ::OS::get_singleton()->can_use_threads(); } -bool _OS::is_userfs_persistent() const { - return OS::get_singleton()->is_userfs_persistent(); +bool OS::is_userfs_persistent() const { + return ::OS::get_singleton()->is_userfs_persistent(); } -int _OS::get_processor_count() const { - return OS::get_singleton()->get_processor_count(); +int OS::get_processor_count() const { + return ::OS::get_singleton()->get_processor_count(); } -bool _OS::is_stdout_verbose() const { - return OS::get_singleton()->is_stdout_verbose(); +bool OS::is_stdout_verbose() const { + return ::OS::get_singleton()->is_stdout_verbose(); } -void _OS::dump_memory_to_file(const String &p_file) { - OS::get_singleton()->dump_memory_to_file(p_file.utf8().get_data()); +void OS::dump_memory_to_file(const String &p_file) { + ::OS::get_singleton()->dump_memory_to_file(p_file.utf8().get_data()); } -struct _OSCoreBindImg { +struct OSCoreBindImg { String path; Size2 size; int fmt = 0; ObjectID id; int vram = 0; - bool operator<(const _OSCoreBindImg &p_img) const { return vram == p_img.vram ? id < p_img.id : vram > p_img.vram; } + bool operator<(const OSCoreBindImg &p_img) const { return vram == p_img.vram ? id < p_img.id : vram > p_img.vram; } }; -void _OS::print_all_textures_by_size() { - List<_OSCoreBindImg> imgs; +void OS::print_all_textures_by_size() { + List<OSCoreBindImg> imgs; uint64_t total = 0; { List<Ref<Resource>> rsrc; @@ -368,7 +370,7 @@ void _OS::print_all_textures_by_size() { Size2 size = res->call("get_size"); int fmt = res->call("get_format"); - _OSCoreBindImg img; + OSCoreBindImg img; img.size = size; img.fmt = fmt; img.path = res->get_path(); @@ -388,7 +390,7 @@ void _OS::print_all_textures_by_size() { "Path - VRAM usage (Dimensions)"); } - for (const _OSCoreBindImg &img : imgs) { + for (const OSCoreBindImg &img : imgs) { print_line(vformat("%s - %s %s", img.path, String::humanize_size(img.vram), @@ -398,7 +400,7 @@ void _OS::print_all_textures_by_size() { print_line(vformat("Total VRAM usage: %s.", String::humanize_size(total))); } -void _OS::print_resources_by_type(const Vector<String> &p_types) { +void OS::print_resources_by_type(const Vector<String> &p_types) { ERR_FAIL_COND_MSG(p_types.size() == 0, "At least one type should be provided to print resources by type."); @@ -440,38 +442,38 @@ void _OS::print_resources_by_type(const Vector<String> &p_types) { } } -void _OS::print_all_resources(const String &p_to_file) { - OS::get_singleton()->print_all_resources(p_to_file); +void OS::print_all_resources(const String &p_to_file) { + ::OS::get_singleton()->print_all_resources(p_to_file); } -void _OS::print_resources_in_use(bool p_short) { - OS::get_singleton()->print_resources_in_use(p_short); +void OS::print_resources_in_use(bool p_short) { + ::OS::get_singleton()->print_resources_in_use(p_short); } -void _OS::dump_resources_to_file(const String &p_file) { - OS::get_singleton()->dump_resources_to_file(p_file.utf8().get_data()); +void OS::dump_resources_to_file(const String &p_file) { + ::OS::get_singleton()->dump_resources_to_file(p_file.utf8().get_data()); } -String _OS::get_user_data_dir() const { - return OS::get_singleton()->get_user_data_dir(); +String OS::get_user_data_dir() const { + return ::OS::get_singleton()->get_user_data_dir(); } -String _OS::get_config_dir() const { +String OS::get_config_dir() const { // Exposed as `get_config_dir()` instead of `get_config_path()` for consistency with other exposed OS methods. - return OS::get_singleton()->get_config_path(); + return ::OS::get_singleton()->get_config_path(); } -String _OS::get_data_dir() const { +String OS::get_data_dir() const { // Exposed as `get_data_dir()` instead of `get_data_path()` for consistency with other exposed OS methods. - return OS::get_singleton()->get_data_path(); + return ::OS::get_singleton()->get_data_path(); } -String _OS::get_cache_dir() const { +String OS::get_cache_dir() const { // Exposed as `get_cache_dir()` instead of `get_cache_path()` for consistency with other exposed OS methods. - return OS::get_singleton()->get_cache_path(); + return ::OS::get_singleton()->get_cache_path(); } -bool _OS::is_debug_build() const { +bool OS::is_debug_build() const { #ifdef DEBUG_ENABLED return true; #else @@ -479,113 +481,113 @@ bool _OS::is_debug_build() const { #endif } -String _OS::get_system_dir(SystemDir p_dir, bool p_shared_storage) const { - return OS::get_singleton()->get_system_dir(OS::SystemDir(p_dir), p_shared_storage); +String OS::get_system_dir(SystemDir p_dir, bool p_shared_storage) const { + return ::OS::get_singleton()->get_system_dir(::OS::SystemDir(p_dir), p_shared_storage); } -String _OS::get_keycode_string(uint32_t p_code) const { - return keycode_get_string(p_code); +String OS::get_keycode_string(uint32_t p_code) const { + return ::keycode_get_string(p_code); } -bool _OS::is_keycode_unicode(uint32_t p_unicode) const { - return keycode_has_unicode(p_unicode); +bool OS::is_keycode_unicode(uint32_t p_unicode) const { + return ::keycode_has_unicode(p_unicode); } -int _OS::find_keycode_from_string(const String &p_code) const { +int OS::find_keycode_from_string(const String &p_code) const { return find_keycode(p_code); } -bool _OS::request_permission(const String &p_name) { - return OS::get_singleton()->request_permission(p_name); +bool OS::request_permission(const String &p_name) { + return ::OS::get_singleton()->request_permission(p_name); } -bool _OS::request_permissions() { - return OS::get_singleton()->request_permissions(); +bool OS::request_permissions() { + return ::OS::get_singleton()->request_permissions(); } -Vector<String> _OS::get_granted_permissions() const { - return OS::get_singleton()->get_granted_permissions(); +Vector<String> OS::get_granted_permissions() const { + return ::OS::get_singleton()->get_granted_permissions(); } -String _OS::get_unique_id() const { - return OS::get_singleton()->get_unique_id(); +String OS::get_unique_id() const { + return ::OS::get_singleton()->get_unique_id(); } -_OS *_OS::singleton = nullptr; +OS *OS::singleton = nullptr; -void _OS::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_connected_midi_inputs"), &_OS::get_connected_midi_inputs); - ClassDB::bind_method(D_METHOD("open_midi_inputs"), &_OS::open_midi_inputs); - ClassDB::bind_method(D_METHOD("close_midi_inputs"), &_OS::close_midi_inputs); +void OS::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_connected_midi_inputs"), &OS::get_connected_midi_inputs); + ClassDB::bind_method(D_METHOD("open_midi_inputs"), &OS::open_midi_inputs); + ClassDB::bind_method(D_METHOD("close_midi_inputs"), &OS::close_midi_inputs); - ClassDB::bind_method(D_METHOD("alert", "text", "title"), &_OS::alert, DEFVAL("Alert!")); + ClassDB::bind_method(D_METHOD("alert", "text", "title"), &OS::alert, DEFVAL("Alert!")); - ClassDB::bind_method(D_METHOD("set_low_processor_usage_mode", "enable"), &_OS::set_low_processor_usage_mode); - ClassDB::bind_method(D_METHOD("is_in_low_processor_usage_mode"), &_OS::is_in_low_processor_usage_mode); + ClassDB::bind_method(D_METHOD("set_low_processor_usage_mode", "enable"), &OS::set_low_processor_usage_mode); + ClassDB::bind_method(D_METHOD("is_in_low_processor_usage_mode"), &OS::is_in_low_processor_usage_mode); - ClassDB::bind_method(D_METHOD("set_low_processor_usage_mode_sleep_usec", "usec"), &_OS::set_low_processor_usage_mode_sleep_usec); - ClassDB::bind_method(D_METHOD("get_low_processor_usage_mode_sleep_usec"), &_OS::get_low_processor_usage_mode_sleep_usec); + ClassDB::bind_method(D_METHOD("set_low_processor_usage_mode_sleep_usec", "usec"), &OS::set_low_processor_usage_mode_sleep_usec); + ClassDB::bind_method(D_METHOD("get_low_processor_usage_mode_sleep_usec"), &OS::get_low_processor_usage_mode_sleep_usec); - ClassDB::bind_method(D_METHOD("get_processor_count"), &_OS::get_processor_count); + ClassDB::bind_method(D_METHOD("get_processor_count"), &OS::get_processor_count); - ClassDB::bind_method(D_METHOD("get_executable_path"), &_OS::get_executable_path); - ClassDB::bind_method(D_METHOD("execute", "path", "arguments", "output", "read_stderr"), &_OS::execute, DEFVAL(Array()), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("create_process", "path", "arguments"), &_OS::create_process); - ClassDB::bind_method(D_METHOD("kill", "pid"), &_OS::kill); - ClassDB::bind_method(D_METHOD("shell_open", "uri"), &_OS::shell_open); - ClassDB::bind_method(D_METHOD("get_process_id"), &_OS::get_process_id); + ClassDB::bind_method(D_METHOD("get_executable_path"), &OS::get_executable_path); + ClassDB::bind_method(D_METHOD("execute", "path", "arguments", "output", "read_stderr"), &OS::execute, DEFVAL(Array()), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("create_process", "path", "arguments"), &OS::create_process); + ClassDB::bind_method(D_METHOD("kill", "pid"), &OS::kill); + ClassDB::bind_method(D_METHOD("shell_open", "uri"), &OS::shell_open); + ClassDB::bind_method(D_METHOD("get_process_id"), &OS::get_process_id); - ClassDB::bind_method(D_METHOD("get_environment", "variable"), &_OS::get_environment); - ClassDB::bind_method(D_METHOD("set_environment", "variable", "value"), &_OS::set_environment); - ClassDB::bind_method(D_METHOD("has_environment", "variable"), &_OS::has_environment); + ClassDB::bind_method(D_METHOD("get_environment", "variable"), &OS::get_environment); + ClassDB::bind_method(D_METHOD("set_environment", "variable", "value"), &OS::set_environment); + ClassDB::bind_method(D_METHOD("has_environment", "variable"), &OS::has_environment); - ClassDB::bind_method(D_METHOD("get_name"), &_OS::get_name); - ClassDB::bind_method(D_METHOD("get_cmdline_args"), &_OS::get_cmdline_args); + ClassDB::bind_method(D_METHOD("get_name"), &OS::get_name); + ClassDB::bind_method(D_METHOD("get_cmdline_args"), &OS::get_cmdline_args); - ClassDB::bind_method(D_METHOD("delay_usec", "usec"), &_OS::delay_usec); - ClassDB::bind_method(D_METHOD("delay_msec", "msec"), &_OS::delay_msec); - ClassDB::bind_method(D_METHOD("get_locale"), &_OS::get_locale); - ClassDB::bind_method(D_METHOD("get_model_name"), &_OS::get_model_name); + ClassDB::bind_method(D_METHOD("delay_usec", "usec"), &OS::delay_usec); + ClassDB::bind_method(D_METHOD("delay_msec", "msec"), &OS::delay_msec); + ClassDB::bind_method(D_METHOD("get_locale"), &OS::get_locale); + ClassDB::bind_method(D_METHOD("get_model_name"), &OS::get_model_name); - ClassDB::bind_method(D_METHOD("is_userfs_persistent"), &_OS::is_userfs_persistent); - ClassDB::bind_method(D_METHOD("is_stdout_verbose"), &_OS::is_stdout_verbose); + ClassDB::bind_method(D_METHOD("is_userfs_persistent"), &OS::is_userfs_persistent); + ClassDB::bind_method(D_METHOD("is_stdout_verbose"), &OS::is_stdout_verbose); - ClassDB::bind_method(D_METHOD("can_use_threads"), &_OS::can_use_threads); + ClassDB::bind_method(D_METHOD("can_use_threads"), &OS::can_use_threads); - ClassDB::bind_method(D_METHOD("is_debug_build"), &_OS::is_debug_build); + ClassDB::bind_method(D_METHOD("is_debug_build"), &OS::is_debug_build); - ClassDB::bind_method(D_METHOD("dump_memory_to_file", "file"), &_OS::dump_memory_to_file); - ClassDB::bind_method(D_METHOD("dump_resources_to_file", "file"), &_OS::dump_resources_to_file); - ClassDB::bind_method(D_METHOD("print_resources_in_use", "short"), &_OS::print_resources_in_use, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("print_all_resources", "tofile"), &_OS::print_all_resources, DEFVAL("")); + ClassDB::bind_method(D_METHOD("dump_memory_to_file", "file"), &OS::dump_memory_to_file); + ClassDB::bind_method(D_METHOD("dump_resources_to_file", "file"), &OS::dump_resources_to_file); + ClassDB::bind_method(D_METHOD("print_resources_in_use", "short"), &OS::print_resources_in_use, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("print_all_resources", "tofile"), &OS::print_all_resources, DEFVAL("")); - ClassDB::bind_method(D_METHOD("get_static_memory_usage"), &_OS::get_static_memory_usage); - ClassDB::bind_method(D_METHOD("get_static_memory_peak_usage"), &_OS::get_static_memory_peak_usage); + ClassDB::bind_method(D_METHOD("get_static_memory_usage"), &OS::get_static_memory_usage); + ClassDB::bind_method(D_METHOD("get_static_memory_peak_usage"), &OS::get_static_memory_peak_usage); - ClassDB::bind_method(D_METHOD("get_user_data_dir"), &_OS::get_user_data_dir); - ClassDB::bind_method(D_METHOD("get_system_dir", "dir", "shared_storage"), &_OS::get_system_dir, DEFVAL(true)); - ClassDB::bind_method(D_METHOD("get_config_dir"), &_OS::get_config_dir); - ClassDB::bind_method(D_METHOD("get_data_dir"), &_OS::get_data_dir); - ClassDB::bind_method(D_METHOD("get_cache_dir"), &_OS::get_cache_dir); - ClassDB::bind_method(D_METHOD("get_unique_id"), &_OS::get_unique_id); + ClassDB::bind_method(D_METHOD("get_user_data_dir"), &OS::get_user_data_dir); + ClassDB::bind_method(D_METHOD("get_system_dir", "dir", "shared_storage"), &OS::get_system_dir, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("get_config_dir"), &OS::get_config_dir); + ClassDB::bind_method(D_METHOD("get_data_dir"), &OS::get_data_dir); + ClassDB::bind_method(D_METHOD("get_cache_dir"), &OS::get_cache_dir); + ClassDB::bind_method(D_METHOD("get_unique_id"), &OS::get_unique_id); - ClassDB::bind_method(D_METHOD("print_all_textures_by_size"), &_OS::print_all_textures_by_size); - ClassDB::bind_method(D_METHOD("print_resources_by_type", "types"), &_OS::print_resources_by_type); + ClassDB::bind_method(D_METHOD("print_all_textures_by_size"), &OS::print_all_textures_by_size); + ClassDB::bind_method(D_METHOD("print_resources_by_type", "types"), &OS::print_resources_by_type); - ClassDB::bind_method(D_METHOD("get_keycode_string", "code"), &_OS::get_keycode_string); - ClassDB::bind_method(D_METHOD("is_keycode_unicode", "code"), &_OS::is_keycode_unicode); - ClassDB::bind_method(D_METHOD("find_keycode_from_string", "string"), &_OS::find_keycode_from_string); + ClassDB::bind_method(D_METHOD("get_keycode_string", "code"), &OS::get_keycode_string); + ClassDB::bind_method(D_METHOD("is_keycode_unicode", "code"), &OS::is_keycode_unicode); + ClassDB::bind_method(D_METHOD("find_keycode_from_string", "string"), &OS::find_keycode_from_string); - ClassDB::bind_method(D_METHOD("set_use_file_access_save_and_swap", "enabled"), &_OS::set_use_file_access_save_and_swap); + ClassDB::bind_method(D_METHOD("set_use_file_access_save_and_swap", "enabled"), &OS::set_use_file_access_save_and_swap); - ClassDB::bind_method(D_METHOD("set_thread_name", "name"), &_OS::set_thread_name); - ClassDB::bind_method(D_METHOD("get_thread_caller_id"), &_OS::get_thread_caller_id); + ClassDB::bind_method(D_METHOD("set_thread_name", "name"), &OS::set_thread_name); + ClassDB::bind_method(D_METHOD("get_thread_caller_id"), &OS::get_thread_caller_id); - ClassDB::bind_method(D_METHOD("has_feature", "tag_name"), &_OS::has_feature); + ClassDB::bind_method(D_METHOD("has_feature", "tag_name"), &OS::has_feature); - ClassDB::bind_method(D_METHOD("request_permission", "name"), &_OS::request_permission); - ClassDB::bind_method(D_METHOD("request_permissions"), &_OS::request_permissions); - ClassDB::bind_method(D_METHOD("get_granted_permissions"), &_OS::get_granted_permissions); + ClassDB::bind_method(D_METHOD("request_permission", "name"), &OS::request_permission); + ClassDB::bind_method(D_METHOD("request_permissions"), &OS::request_permissions); + ClassDB::bind_method(D_METHOD("get_granted_permissions"), &OS::get_granted_permissions); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "low_processor_usage_mode"), "set_low_processor_usage_mode", "is_in_low_processor_usage_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "low_processor_usage_mode_sleep_usec"), "set_low_processor_usage_mode_sleep_usec", "get_low_processor_usage_mode_sleep_usec"); @@ -630,43 +632,43 @@ void _OS::_bind_methods() { BIND_ENUM_CONSTANT(SYSTEM_DIR_RINGTONES); } -////// _Geometry2D ////// +////// Geometry2D ////// -_Geometry2D *_Geometry2D::singleton = nullptr; +Geometry2D *Geometry2D::singleton = nullptr; -_Geometry2D *_Geometry2D::get_singleton() { +Geometry2D *Geometry2D::get_singleton() { return singleton; } -bool _Geometry2D::is_point_in_circle(const Vector2 &p_point, const Vector2 &p_circle_pos, real_t p_circle_radius) { - return Geometry2D::is_point_in_circle(p_point, p_circle_pos, p_circle_radius); +bool Geometry2D::is_point_in_circle(const Vector2 &p_point, const Vector2 &p_circle_pos, real_t p_circle_radius) { + return ::Geometry2D::is_point_in_circle(p_point, p_circle_pos, p_circle_radius); } -real_t _Geometry2D::segment_intersects_circle(const Vector2 &p_from, const Vector2 &p_to, const Vector2 &p_circle_pos, real_t p_circle_radius) { - return Geometry2D::segment_intersects_circle(p_from, p_to, p_circle_pos, p_circle_radius); +real_t Geometry2D::segment_intersects_circle(const Vector2 &p_from, const Vector2 &p_to, const Vector2 &p_circle_pos, real_t p_circle_radius) { + return ::Geometry2D::segment_intersects_circle(p_from, p_to, p_circle_pos, p_circle_radius); } -Variant _Geometry2D::segment_intersects_segment(const Vector2 &p_from_a, const Vector2 &p_to_a, const Vector2 &p_from_b, const Vector2 &p_to_b) { +Variant Geometry2D::segment_intersects_segment(const Vector2 &p_from_a, const Vector2 &p_to_a, const Vector2 &p_from_b, const Vector2 &p_to_b) { Vector2 result; - if (Geometry2D::segment_intersects_segment(p_from_a, p_to_a, p_from_b, p_to_b, &result)) { + if (::Geometry2D::segment_intersects_segment(p_from_a, p_to_a, p_from_b, p_to_b, &result)) { return result; } else { return Variant(); } } -Variant _Geometry2D::line_intersects_line(const Vector2 &p_from_a, const Vector2 &p_dir_a, const Vector2 &p_from_b, const Vector2 &p_dir_b) { +Variant Geometry2D::line_intersects_line(const Vector2 &p_from_a, const Vector2 &p_dir_a, const Vector2 &p_from_b, const Vector2 &p_dir_b) { Vector2 result; - if (Geometry2D::line_intersects_line(p_from_a, p_dir_a, p_from_b, p_dir_b, result)) { + if (::Geometry2D::line_intersects_line(p_from_a, p_dir_a, p_from_b, p_dir_b, result)) { return result; } else { return Variant(); } } -Vector<Vector2> _Geometry2D::get_closest_points_between_segments(const Vector2 &p1, const Vector2 &q1, const Vector2 &p2, const Vector2 &q2) { +Vector<Vector2> Geometry2D::get_closest_points_between_segments(const Vector2 &p1, const Vector2 &q1, const Vector2 &p2, const Vector2 &q2) { Vector2 r1, r2; - Geometry2D::get_closest_points_between_segments(p1, q1, p2, q2, r1, r2); + ::Geometry2D::get_closest_points_between_segments(p1, q1, p2, q2, r1, r2); Vector<Vector2> r; r.resize(2); r.set(0, r1); @@ -674,42 +676,42 @@ Vector<Vector2> _Geometry2D::get_closest_points_between_segments(const Vector2 & return r; } -Vector2 _Geometry2D::get_closest_point_to_segment(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b) { +Vector2 Geometry2D::get_closest_point_to_segment(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b) { Vector2 s[2] = { p_a, p_b }; - return Geometry2D::get_closest_point_to_segment(p_point, s); + return ::Geometry2D::get_closest_point_to_segment(p_point, s); } -Vector2 _Geometry2D::get_closest_point_to_segment_uncapped(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b) { +Vector2 Geometry2D::get_closest_point_to_segment_uncapped(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b) { Vector2 s[2] = { p_a, p_b }; - return Geometry2D::get_closest_point_to_segment_uncapped(p_point, s); + return ::Geometry2D::get_closest_point_to_segment_uncapped(p_point, s); } -bool _Geometry2D::point_is_inside_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) const { - return Geometry2D::is_point_in_triangle(s, a, b, c); +bool Geometry2D::point_is_inside_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) const { + return ::Geometry2D::is_point_in_triangle(s, a, b, c); } -bool _Geometry2D::is_polygon_clockwise(const Vector<Vector2> &p_polygon) { - return Geometry2D::is_polygon_clockwise(p_polygon); +bool Geometry2D::is_polygon_clockwise(const Vector<Vector2> &p_polygon) { + return ::Geometry2D::is_polygon_clockwise(p_polygon); } -bool _Geometry2D::is_point_in_polygon(const Point2 &p_point, const Vector<Vector2> &p_polygon) { - return Geometry2D::is_point_in_polygon(p_point, p_polygon); +bool Geometry2D::is_point_in_polygon(const Point2 &p_point, const Vector<Vector2> &p_polygon) { + return ::Geometry2D::is_point_in_polygon(p_point, p_polygon); } -Vector<int> _Geometry2D::triangulate_polygon(const Vector<Vector2> &p_polygon) { - return Geometry2D::triangulate_polygon(p_polygon); +Vector<int> Geometry2D::triangulate_polygon(const Vector<Vector2> &p_polygon) { + return ::Geometry2D::triangulate_polygon(p_polygon); } -Vector<int> _Geometry2D::triangulate_delaunay(const Vector<Vector2> &p_points) { - return Geometry2D::triangulate_delaunay(p_points); +Vector<int> Geometry2D::triangulate_delaunay(const Vector<Vector2> &p_points) { + return ::Geometry2D::triangulate_delaunay(p_points); } -Vector<Point2> _Geometry2D::convex_hull(const Vector<Point2> &p_points) { - return Geometry2D::convex_hull(p_points); +Vector<Point2> Geometry2D::convex_hull(const Vector<Point2> &p_points) { + return ::Geometry2D::convex_hull(p_points); } -Array _Geometry2D::merge_polygons(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b) { - Vector<Vector<Point2>> polys = Geometry2D::merge_polygons(p_polygon_a, p_polygon_b); +Array Geometry2D::merge_polygons(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b) { + Vector<Vector<Point2>> polys = ::Geometry2D::merge_polygons(p_polygon_a, p_polygon_b); Array ret; @@ -719,8 +721,8 @@ Array _Geometry2D::merge_polygons(const Vector<Vector2> &p_polygon_a, const Vect return ret; } -Array _Geometry2D::clip_polygons(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b) { - Vector<Vector<Point2>> polys = Geometry2D::clip_polygons(p_polygon_a, p_polygon_b); +Array Geometry2D::clip_polygons(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b) { + Vector<Vector<Point2>> polys = ::Geometry2D::clip_polygons(p_polygon_a, p_polygon_b); Array ret; @@ -730,8 +732,8 @@ Array _Geometry2D::clip_polygons(const Vector<Vector2> &p_polygon_a, const Vecto return ret; } -Array _Geometry2D::intersect_polygons(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b) { - Vector<Vector<Point2>> polys = Geometry2D::intersect_polygons(p_polygon_a, p_polygon_b); +Array Geometry2D::intersect_polygons(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b) { + Vector<Vector<Point2>> polys = ::Geometry2D::intersect_polygons(p_polygon_a, p_polygon_b); Array ret; @@ -741,8 +743,8 @@ Array _Geometry2D::intersect_polygons(const Vector<Vector2> &p_polygon_a, const return ret; } -Array _Geometry2D::exclude_polygons(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b) { - Vector<Vector<Point2>> polys = Geometry2D::exclude_polygons(p_polygon_a, p_polygon_b); +Array Geometry2D::exclude_polygons(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b) { + Vector<Vector<Point2>> polys = ::Geometry2D::exclude_polygons(p_polygon_a, p_polygon_b); Array ret; @@ -752,8 +754,8 @@ Array _Geometry2D::exclude_polygons(const Vector<Vector2> &p_polygon_a, const Ve return ret; } -Array _Geometry2D::clip_polyline_with_polygon(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon) { - Vector<Vector<Point2>> polys = Geometry2D::clip_polyline_with_polygon(p_polyline, p_polygon); +Array Geometry2D::clip_polyline_with_polygon(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon) { + Vector<Vector<Point2>> polys = ::Geometry2D::clip_polyline_with_polygon(p_polyline, p_polygon); Array ret; @@ -763,8 +765,8 @@ Array _Geometry2D::clip_polyline_with_polygon(const Vector<Vector2> &p_polyline, return ret; } -Array _Geometry2D::intersect_polyline_with_polygon(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon) { - Vector<Vector<Point2>> polys = Geometry2D::intersect_polyline_with_polygon(p_polyline, p_polygon); +Array Geometry2D::intersect_polyline_with_polygon(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon) { + Vector<Vector<Point2>> polys = ::Geometry2D::intersect_polyline_with_polygon(p_polyline, p_polygon); Array ret; @@ -774,8 +776,8 @@ Array _Geometry2D::intersect_polyline_with_polygon(const Vector<Vector2> &p_poly return ret; } -Array _Geometry2D::offset_polygon(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type) { - Vector<Vector<Point2>> polys = Geometry2D::offset_polygon(p_polygon, p_delta, Geometry2D::PolyJoinType(p_join_type)); +Array Geometry2D::offset_polygon(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type) { + Vector<Vector<Point2>> polys = ::Geometry2D::offset_polygon(p_polygon, p_delta, ::Geometry2D::PolyJoinType(p_join_type)); Array ret; @@ -785,8 +787,8 @@ Array _Geometry2D::offset_polygon(const Vector<Vector2> &p_polygon, real_t p_del return ret; } -Array _Geometry2D::offset_polyline(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) { - Vector<Vector<Point2>> polys = Geometry2D::offset_polyline(p_polygon, p_delta, Geometry2D::PolyJoinType(p_join_type), Geometry2D::PolyEndType(p_end_type)); +Array Geometry2D::offset_polyline(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) { + Vector<Vector<Point2>> polys = ::Geometry2D::offset_polyline(p_polygon, p_delta, ::Geometry2D::PolyJoinType(p_join_type), ::Geometry2D::PolyEndType(p_end_type)); Array ret; @@ -796,7 +798,7 @@ Array _Geometry2D::offset_polyline(const Vector<Vector2> &p_polygon, real_t p_de return ret; } -Dictionary _Geometry2D::make_atlas(const Vector<Size2> &p_rects) { +Dictionary Geometry2D::make_atlas(const Vector<Size2> &p_rects) { Dictionary ret; Vector<Size2i> rects; @@ -807,7 +809,7 @@ Dictionary _Geometry2D::make_atlas(const Vector<Size2> &p_rects) { Vector<Point2i> result; Size2i size; - Geometry2D::make_atlas(rects, result, size); + ::Geometry2D::make_atlas(rects, result, size); Size2 r_size = size; Vector<Point2> r_result; @@ -821,37 +823,37 @@ Dictionary _Geometry2D::make_atlas(const Vector<Size2> &p_rects) { return ret; } -void _Geometry2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("is_point_in_circle", "point", "circle_position", "circle_radius"), &_Geometry2D::is_point_in_circle); - ClassDB::bind_method(D_METHOD("segment_intersects_segment", "from_a", "to_a", "from_b", "to_b"), &_Geometry2D::segment_intersects_segment); - ClassDB::bind_method(D_METHOD("line_intersects_line", "from_a", "dir_a", "from_b", "dir_b"), &_Geometry2D::line_intersects_line); +void Geometry2D::_bind_methods() { + ClassDB::bind_method(D_METHOD("is_point_in_circle", "point", "circle_position", "circle_radius"), &Geometry2D::is_point_in_circle); + ClassDB::bind_method(D_METHOD("segment_intersects_segment", "from_a", "to_a", "from_b", "to_b"), &Geometry2D::segment_intersects_segment); + ClassDB::bind_method(D_METHOD("line_intersects_line", "from_a", "dir_a", "from_b", "dir_b"), &Geometry2D::line_intersects_line); - ClassDB::bind_method(D_METHOD("get_closest_points_between_segments", "p1", "q1", "p2", "q2"), &_Geometry2D::get_closest_points_between_segments); + ClassDB::bind_method(D_METHOD("get_closest_points_between_segments", "p1", "q1", "p2", "q2"), &Geometry2D::get_closest_points_between_segments); - ClassDB::bind_method(D_METHOD("get_closest_point_to_segment", "point", "s1", "s2"), &_Geometry2D::get_closest_point_to_segment); + ClassDB::bind_method(D_METHOD("get_closest_point_to_segment", "point", "s1", "s2"), &Geometry2D::get_closest_point_to_segment); - ClassDB::bind_method(D_METHOD("get_closest_point_to_segment_uncapped", "point", "s1", "s2"), &_Geometry2D::get_closest_point_to_segment_uncapped); + ClassDB::bind_method(D_METHOD("get_closest_point_to_segment_uncapped", "point", "s1", "s2"), &Geometry2D::get_closest_point_to_segment_uncapped); - ClassDB::bind_method(D_METHOD("point_is_inside_triangle", "point", "a", "b", "c"), &_Geometry2D::point_is_inside_triangle); + ClassDB::bind_method(D_METHOD("point_is_inside_triangle", "point", "a", "b", "c"), &Geometry2D::point_is_inside_triangle); - ClassDB::bind_method(D_METHOD("is_polygon_clockwise", "polygon"), &_Geometry2D::is_polygon_clockwise); - ClassDB::bind_method(D_METHOD("is_point_in_polygon", "point", "polygon"), &_Geometry2D::is_point_in_polygon); - ClassDB::bind_method(D_METHOD("triangulate_polygon", "polygon"), &_Geometry2D::triangulate_polygon); - ClassDB::bind_method(D_METHOD("triangulate_delaunay", "points"), &_Geometry2D::triangulate_delaunay); - ClassDB::bind_method(D_METHOD("convex_hull", "points"), &_Geometry2D::convex_hull); + ClassDB::bind_method(D_METHOD("is_polygon_clockwise", "polygon"), &Geometry2D::is_polygon_clockwise); + ClassDB::bind_method(D_METHOD("is_point_in_polygon", "point", "polygon"), &Geometry2D::is_point_in_polygon); + ClassDB::bind_method(D_METHOD("triangulate_polygon", "polygon"), &Geometry2D::triangulate_polygon); + ClassDB::bind_method(D_METHOD("triangulate_delaunay", "points"), &Geometry2D::triangulate_delaunay); + ClassDB::bind_method(D_METHOD("convex_hull", "points"), &Geometry2D::convex_hull); - ClassDB::bind_method(D_METHOD("merge_polygons", "polygon_a", "polygon_b"), &_Geometry2D::merge_polygons); - ClassDB::bind_method(D_METHOD("clip_polygons", "polygon_a", "polygon_b"), &_Geometry2D::clip_polygons); - ClassDB::bind_method(D_METHOD("intersect_polygons", "polygon_a", "polygon_b"), &_Geometry2D::intersect_polygons); - ClassDB::bind_method(D_METHOD("exclude_polygons", "polygon_a", "polygon_b"), &_Geometry2D::exclude_polygons); + ClassDB::bind_method(D_METHOD("merge_polygons", "polygon_a", "polygon_b"), &Geometry2D::merge_polygons); + ClassDB::bind_method(D_METHOD("clip_polygons", "polygon_a", "polygon_b"), &Geometry2D::clip_polygons); + ClassDB::bind_method(D_METHOD("intersect_polygons", "polygon_a", "polygon_b"), &Geometry2D::intersect_polygons); + ClassDB::bind_method(D_METHOD("exclude_polygons", "polygon_a", "polygon_b"), &Geometry2D::exclude_polygons); - ClassDB::bind_method(D_METHOD("clip_polyline_with_polygon", "polyline", "polygon"), &_Geometry2D::clip_polyline_with_polygon); - ClassDB::bind_method(D_METHOD("intersect_polyline_with_polygon", "polyline", "polygon"), &_Geometry2D::intersect_polyline_with_polygon); + ClassDB::bind_method(D_METHOD("clip_polyline_with_polygon", "polyline", "polygon"), &Geometry2D::clip_polyline_with_polygon); + ClassDB::bind_method(D_METHOD("intersect_polyline_with_polygon", "polyline", "polygon"), &Geometry2D::intersect_polyline_with_polygon); - ClassDB::bind_method(D_METHOD("offset_polygon", "polygon", "delta", "join_type"), &_Geometry2D::offset_polygon, DEFVAL(JOIN_SQUARE)); - ClassDB::bind_method(D_METHOD("offset_polyline", "polyline", "delta", "join_type", "end_type"), &_Geometry2D::offset_polyline, DEFVAL(JOIN_SQUARE), DEFVAL(END_SQUARE)); + ClassDB::bind_method(D_METHOD("offset_polygon", "polygon", "delta", "join_type"), &Geometry2D::offset_polygon, DEFVAL(JOIN_SQUARE)); + ClassDB::bind_method(D_METHOD("offset_polyline", "polyline", "delta", "join_type", "end_type"), &Geometry2D::offset_polyline, DEFVAL(JOIN_SQUARE), DEFVAL(END_SQUARE)); - ClassDB::bind_method(D_METHOD("make_atlas", "sizes"), &_Geometry2D::make_atlas); + ClassDB::bind_method(D_METHOD("make_atlas", "sizes"), &Geometry2D::make_atlas); BIND_ENUM_CONSTANT(OPERATION_UNION); BIND_ENUM_CONSTANT(OPERATION_DIFFERENCE); @@ -869,29 +871,29 @@ void _Geometry2D::_bind_methods() { BIND_ENUM_CONSTANT(END_ROUND); } -////// _Geometry3D ////// +////// Geometry3D ////// -_Geometry3D *_Geometry3D::singleton = nullptr; +Geometry3D *Geometry3D::singleton = nullptr; -_Geometry3D *_Geometry3D::get_singleton() { +Geometry3D *Geometry3D::get_singleton() { return singleton; } -Vector<Plane> _Geometry3D::build_box_planes(const Vector3 &p_extents) { - return Geometry3D::build_box_planes(p_extents); +Vector<Plane> Geometry3D::build_box_planes(const Vector3 &p_extents) { + return ::Geometry3D::build_box_planes(p_extents); } -Vector<Plane> _Geometry3D::build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis) { - return Geometry3D::build_cylinder_planes(p_radius, p_height, p_sides, p_axis); +Vector<Plane> Geometry3D::build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis) { + return ::Geometry3D::build_cylinder_planes(p_radius, p_height, p_sides, p_axis); } -Vector<Plane> _Geometry3D::build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis) { - return Geometry3D::build_capsule_planes(p_radius, p_height, p_sides, p_lats, p_axis); +Vector<Plane> Geometry3D::build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis) { + return ::Geometry3D::build_capsule_planes(p_radius, p_height, p_sides, p_lats, p_axis); } -Vector<Vector3> _Geometry3D::get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2) { +Vector<Vector3> Geometry3D::get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2) { Vector3 r1, r2; - Geometry3D::get_closest_points_between_segments(p1, p2, q1, q2, r1, r2); + ::Geometry3D::get_closest_points_between_segments(p1, p2, q1, q2, r1, r2); Vector<Vector3> r; r.resize(2); r.set(0, r1); @@ -899,38 +901,38 @@ Vector<Vector3> _Geometry3D::get_closest_points_between_segments(const Vector3 & return r; } -Vector3 _Geometry3D::get_closest_point_to_segment(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b) { +Vector3 Geometry3D::get_closest_point_to_segment(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b) { Vector3 s[2] = { p_a, p_b }; - return Geometry3D::get_closest_point_to_segment(p_point, s); + return ::Geometry3D::get_closest_point_to_segment(p_point, s); } -Vector3 _Geometry3D::get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b) { +Vector3 Geometry3D::get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b) { Vector3 s[2] = { p_a, p_b }; - return Geometry3D::get_closest_point_to_segment_uncapped(p_point, s); + return ::Geometry3D::get_closest_point_to_segment_uncapped(p_point, s); } -Variant _Geometry3D::ray_intersects_triangle(const Vector3 &p_from, const Vector3 &p_dir, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2) { +Variant Geometry3D::ray_intersects_triangle(const Vector3 &p_from, const Vector3 &p_dir, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2) { Vector3 res; - if (Geometry3D::ray_intersects_triangle(p_from, p_dir, p_v0, p_v1, p_v2, &res)) { + if (::Geometry3D::ray_intersects_triangle(p_from, p_dir, p_v0, p_v1, p_v2, &res)) { return res; } else { return Variant(); } } -Variant _Geometry3D::segment_intersects_triangle(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2) { +Variant Geometry3D::segment_intersects_triangle(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2) { Vector3 res; - if (Geometry3D::segment_intersects_triangle(p_from, p_to, p_v0, p_v1, p_v2, &res)) { + if (::Geometry3D::segment_intersects_triangle(p_from, p_to, p_v0, p_v1, p_v2, &res)) { return res; } else { return Variant(); } } -Vector<Vector3> _Geometry3D::segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius) { +Vector<Vector3> Geometry3D::segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius) { Vector<Vector3> r; Vector3 res, norm; - if (!Geometry3D::segment_intersects_sphere(p_from, p_to, p_sphere_pos, p_sphere_radius, &res, &norm)) { + if (!::Geometry3D::segment_intersects_sphere(p_from, p_to, p_sphere_pos, p_sphere_radius, &res, &norm)) { return r; } @@ -940,10 +942,10 @@ Vector<Vector3> _Geometry3D::segment_intersects_sphere(const Vector3 &p_from, co return r; } -Vector<Vector3> _Geometry3D::segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, float p_height, float p_radius) { +Vector<Vector3> Geometry3D::segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, float p_height, float p_radius) { Vector<Vector3> r; Vector3 res, norm; - if (!Geometry3D::segment_intersects_cylinder(p_from, p_to, p_height, p_radius, &res, &norm)) { + if (!::Geometry3D::segment_intersects_cylinder(p_from, p_to, p_height, p_radius, &res, &norm)) { return r; } @@ -953,10 +955,10 @@ Vector<Vector3> _Geometry3D::segment_intersects_cylinder(const Vector3 &p_from, return r; } -Vector<Vector3> _Geometry3D::segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Vector<Plane> &p_planes) { +Vector<Vector3> Geometry3D::segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Vector<Plane> &p_planes) { Vector<Vector3> r; Vector3 res, norm; - if (!Geometry3D::segment_intersects_convex(p_from, p_to, p_planes.ptr(), p_planes.size(), &res, &norm)) { + if (!::Geometry3D::segment_intersects_convex(p_from, p_to, p_planes.ptr(), p_planes.size(), &res, &norm)) { return r; } @@ -966,33 +968,33 @@ Vector<Vector3> _Geometry3D::segment_intersects_convex(const Vector3 &p_from, co return r; } -Vector<Vector3> _Geometry3D::clip_polygon(const Vector<Vector3> &p_points, const Plane &p_plane) { - return Geometry3D::clip_polygon(p_points, p_plane); +Vector<Vector3> Geometry3D::clip_polygon(const Vector<Vector3> &p_points, const Plane &p_plane) { + return ::Geometry3D::clip_polygon(p_points, p_plane); } -void _Geometry3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("build_box_planes", "extents"), &_Geometry3D::build_box_planes); - ClassDB::bind_method(D_METHOD("build_cylinder_planes", "radius", "height", "sides", "axis"), &_Geometry3D::build_cylinder_planes, DEFVAL(Vector3::AXIS_Z)); - ClassDB::bind_method(D_METHOD("build_capsule_planes", "radius", "height", "sides", "lats", "axis"), &_Geometry3D::build_capsule_planes, DEFVAL(Vector3::AXIS_Z)); +void Geometry3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("build_box_planes", "extents"), &Geometry3D::build_box_planes); + ClassDB::bind_method(D_METHOD("build_cylinder_planes", "radius", "height", "sides", "axis"), &Geometry3D::build_cylinder_planes, DEFVAL(Vector3::AXIS_Z)); + ClassDB::bind_method(D_METHOD("build_capsule_planes", "radius", "height", "sides", "lats", "axis"), &Geometry3D::build_capsule_planes, DEFVAL(Vector3::AXIS_Z)); - ClassDB::bind_method(D_METHOD("get_closest_points_between_segments", "p1", "p2", "q1", "q2"), &_Geometry3D::get_closest_points_between_segments); + ClassDB::bind_method(D_METHOD("get_closest_points_between_segments", "p1", "p2", "q1", "q2"), &Geometry3D::get_closest_points_between_segments); - ClassDB::bind_method(D_METHOD("get_closest_point_to_segment", "point", "s1", "s2"), &_Geometry3D::get_closest_point_to_segment); + ClassDB::bind_method(D_METHOD("get_closest_point_to_segment", "point", "s1", "s2"), &Geometry3D::get_closest_point_to_segment); - ClassDB::bind_method(D_METHOD("get_closest_point_to_segment_uncapped", "point", "s1", "s2"), &_Geometry3D::get_closest_point_to_segment_uncapped); + ClassDB::bind_method(D_METHOD("get_closest_point_to_segment_uncapped", "point", "s1", "s2"), &Geometry3D::get_closest_point_to_segment_uncapped); - ClassDB::bind_method(D_METHOD("ray_intersects_triangle", "from", "dir", "a", "b", "c"), &_Geometry3D::ray_intersects_triangle); - ClassDB::bind_method(D_METHOD("segment_intersects_triangle", "from", "to", "a", "b", "c"), &_Geometry3D::segment_intersects_triangle); - ClassDB::bind_method(D_METHOD("segment_intersects_sphere", "from", "to", "sphere_position", "sphere_radius"), &_Geometry3D::segment_intersects_sphere); - ClassDB::bind_method(D_METHOD("segment_intersects_cylinder", "from", "to", "height", "radius"), &_Geometry3D::segment_intersects_cylinder); - ClassDB::bind_method(D_METHOD("segment_intersects_convex", "from", "to", "planes"), &_Geometry3D::segment_intersects_convex); + ClassDB::bind_method(D_METHOD("ray_intersects_triangle", "from", "dir", "a", "b", "c"), &Geometry3D::ray_intersects_triangle); + ClassDB::bind_method(D_METHOD("segment_intersects_triangle", "from", "to", "a", "b", "c"), &Geometry3D::segment_intersects_triangle); + ClassDB::bind_method(D_METHOD("segment_intersects_sphere", "from", "to", "sphere_position", "sphere_radius"), &Geometry3D::segment_intersects_sphere); + ClassDB::bind_method(D_METHOD("segment_intersects_cylinder", "from", "to", "height", "radius"), &Geometry3D::segment_intersects_cylinder); + ClassDB::bind_method(D_METHOD("segment_intersects_convex", "from", "to", "planes"), &Geometry3D::segment_intersects_convex); - ClassDB::bind_method(D_METHOD("clip_polygon", "points", "plane"), &_Geometry3D::clip_polygon); + ClassDB::bind_method(D_METHOD("clip_polygon", "points", "plane"), &Geometry3D::clip_polygon); } -////// _File ////// +////// File ////// -Error _File::open_encrypted(const String &p_path, ModeFlags p_mode_flags, const Vector<uint8_t> &p_key) { +Error File::open_encrypted(const String &p_path, ModeFlags p_mode_flags, const Vector<uint8_t> &p_key) { Error err = open(p_path, p_mode_flags); if (err) { return err; @@ -1009,7 +1011,7 @@ Error _File::open_encrypted(const String &p_path, ModeFlags p_mode_flags, const return OK; } -Error _File::open_encrypted_pass(const String &p_path, ModeFlags p_mode_flags, const String &p_pass) { +Error File::open_encrypted_pass(const String &p_path, ModeFlags p_mode_flags, const String &p_pass) { Error err = open(p_path, p_mode_flags); if (err) { return err; @@ -1027,7 +1029,7 @@ Error _File::open_encrypted_pass(const String &p_path, ModeFlags p_mode_flags, c return OK; } -Error _File::open_compressed(const String &p_path, ModeFlags p_mode_flags, CompressionMode p_compress_mode) { +Error File::open_compressed(const String &p_path, ModeFlags p_mode_flags, CompressionMode p_compress_mode) { FileAccessCompressed *fac = memnew(FileAccessCompressed); fac->configure("GCPF", (Compression::Mode)p_compress_mode); @@ -1043,7 +1045,7 @@ Error _File::open_compressed(const String &p_path, ModeFlags p_mode_flags, Compr return OK; } -Error _File::open(const String &p_path, ModeFlags p_mode_flags) { +Error File::open(const String &p_path, ModeFlags p_mode_flags) { close(); Error err; f = FileAccess::open(p_path, p_mode_flags, &err); @@ -1053,94 +1055,94 @@ Error _File::open(const String &p_path, ModeFlags p_mode_flags) { return err; } -void _File::flush() { +void File::flush() { ERR_FAIL_COND_MSG(!f, "File must be opened before flushing."); f->flush(); } -void _File::close() { +void File::close() { if (f) { memdelete(f); } f = nullptr; } -bool _File::is_open() const { +bool File::is_open() const { return f != nullptr; } -String _File::get_path() const { +String File::get_path() const { ERR_FAIL_COND_V_MSG(!f, "", "File must be opened before use."); return f->get_path(); } -String _File::get_path_absolute() const { +String File::get_path_absolute() const { ERR_FAIL_COND_V_MSG(!f, "", "File must be opened before use."); return f->get_path_absolute(); } -void _File::seek(int64_t p_position) { +void File::seek(int64_t p_position) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); ERR_FAIL_COND_MSG(p_position < 0, "Seek position must be a positive integer."); f->seek(p_position); } -void _File::seek_end(int64_t p_position) { +void File::seek_end(int64_t p_position) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); f->seek_end(p_position); } -uint64_t _File::get_position() const { +uint64_t File::get_position() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); return f->get_position(); } -uint64_t _File::get_length() const { +uint64_t File::get_length() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); return f->get_length(); } -bool _File::eof_reached() const { +bool File::eof_reached() const { ERR_FAIL_COND_V_MSG(!f, false, "File must be opened before use."); return f->eof_reached(); } -uint8_t _File::get_8() const { +uint8_t File::get_8() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); return f->get_8(); } -uint16_t _File::get_16() const { +uint16_t File::get_16() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); return f->get_16(); } -uint32_t _File::get_32() const { +uint32_t File::get_32() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); return f->get_32(); } -uint64_t _File::get_64() const { +uint64_t File::get_64() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); return f->get_64(); } -float _File::get_float() const { +float File::get_float() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); return f->get_float(); } -double _File::get_double() const { +double File::get_double() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); return f->get_double(); } -real_t _File::get_real() const { +real_t File::get_real() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); return f->get_real(); } -Vector<uint8_t> _File::get_buffer(int64_t p_length) const { +Vector<uint8_t> File::get_buffer(int64_t p_length) const { Vector<uint8_t> data; ERR_FAIL_COND_V_MSG(!f, data, "File must be opened before use."); @@ -1162,7 +1164,7 @@ Vector<uint8_t> _File::get_buffer(int64_t p_length) const { return data; } -String _File::get_as_text() const { +String File::get_as_text() const { ERR_FAIL_COND_V_MSG(!f, String(), "File must be opened before use."); String text; @@ -1181,20 +1183,20 @@ String _File::get_as_text() const { return text; } -String _File::get_md5(const String &p_path) const { +String File::get_md5(const String &p_path) const { return FileAccess::get_md5(p_path); } -String _File::get_sha256(const String &p_path) const { +String File::get_sha256(const String &p_path) const { return FileAccess::get_sha256(p_path); } -String _File::get_line() const { +String File::get_line() const { ERR_FAIL_COND_V_MSG(!f, String(), "File must be opened before use."); return f->get_line(); } -Vector<String> _File::get_csv_line(const String &p_delim) const { +Vector<String> File::get_csv_line(const String &p_delim) const { ERR_FAIL_COND_V_MSG(!f, Vector<String>(), "File must be opened before use."); return f->get_csv_line(p_delim); } @@ -1204,95 +1206,95 @@ Vector<String> _File::get_csv_line(const String &p_delim) const { * These flags get reset to false (little endian) on each open */ -void _File::set_big_endian(bool p_big_endian) { +void File::set_big_endian(bool p_big_endian) { big_endian = p_big_endian; if (f) { f->set_big_endian(p_big_endian); } } -bool _File::is_big_endian() { +bool File::is_big_endian() { return big_endian; } -Error _File::get_error() const { +Error File::get_error() const { if (!f) { return ERR_UNCONFIGURED; } return f->get_error(); } -void _File::store_8(uint8_t p_dest) { +void File::store_8(uint8_t p_dest) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); f->store_8(p_dest); } -void _File::store_16(uint16_t p_dest) { +void File::store_16(uint16_t p_dest) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); f->store_16(p_dest); } -void _File::store_32(uint32_t p_dest) { +void File::store_32(uint32_t p_dest) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); f->store_32(p_dest); } -void _File::store_64(uint64_t p_dest) { +void File::store_64(uint64_t p_dest) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); f->store_64(p_dest); } -void _File::store_float(float p_dest) { +void File::store_float(float p_dest) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); f->store_float(p_dest); } -void _File::store_double(double p_dest) { +void File::store_double(double p_dest) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); f->store_double(p_dest); } -void _File::store_real(real_t p_real) { +void File::store_real(real_t p_real) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); f->store_real(p_real); } -void _File::store_string(const String &p_string) { +void File::store_string(const String &p_string) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); f->store_string(p_string); } -void _File::store_pascal_string(const String &p_string) { +void File::store_pascal_string(const String &p_string) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); f->store_pascal_string(p_string); } -String _File::get_pascal_string() { +String File::get_pascal_string() { ERR_FAIL_COND_V_MSG(!f, "", "File must be opened before use."); return f->get_pascal_string(); } -void _File::store_line(const String &p_string) { +void File::store_line(const String &p_string) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); f->store_line(p_string); } -void _File::store_csv_line(const Vector<String> &p_values, const String &p_delim) { +void File::store_csv_line(const Vector<String> &p_values, const String &p_delim) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); f->store_csv_line(p_values, p_delim); } -void _File::store_buffer(const Vector<uint8_t> &p_buffer) { +void File::store_buffer(const Vector<uint8_t> &p_buffer) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); uint64_t len = p_buffer.size(); @@ -1305,11 +1307,11 @@ void _File::store_buffer(const Vector<uint8_t> &p_buffer) { f->store_buffer(&r[0], len); } -bool _File::file_exists(const String &p_name) const { +bool File::file_exists(const String &p_name) const { return FileAccess::exists(p_name); } -void _File::store_var(const Variant &p_var, bool p_full_objects) { +void File::store_var(const Variant &p_var, bool p_full_objects) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); int len; Error err = encode_variant(p_var, nullptr, len, p_full_objects); @@ -1326,7 +1328,7 @@ void _File::store_var(const Variant &p_var, bool p_full_objects) { store_buffer(buff); } -Variant _File::get_var(bool p_allow_objects) const { +Variant File::get_var(bool p_allow_objects) const { ERR_FAIL_COND_V_MSG(!f, Variant(), "File must be opened before use."); uint32_t len = get_32(); Vector<uint8_t> buff = get_buffer(len); @@ -1341,62 +1343,62 @@ Variant _File::get_var(bool p_allow_objects) const { return v; } -uint64_t _File::get_modified_time(const String &p_file) const { +uint64_t File::get_modified_time(const String &p_file) const { return FileAccess::get_modified_time(p_file); } -void _File::_bind_methods() { - ClassDB::bind_method(D_METHOD("open_encrypted", "path", "mode_flags", "key"), &_File::open_encrypted); - ClassDB::bind_method(D_METHOD("open_encrypted_with_pass", "path", "mode_flags", "pass"), &_File::open_encrypted_pass); - ClassDB::bind_method(D_METHOD("open_compressed", "path", "mode_flags", "compression_mode"), &_File::open_compressed, DEFVAL(0)); - - ClassDB::bind_method(D_METHOD("open", "path", "flags"), &_File::open); - ClassDB::bind_method(D_METHOD("flush"), &_File::flush); - ClassDB::bind_method(D_METHOD("close"), &_File::close); - ClassDB::bind_method(D_METHOD("get_path"), &_File::get_path); - ClassDB::bind_method(D_METHOD("get_path_absolute"), &_File::get_path_absolute); - ClassDB::bind_method(D_METHOD("is_open"), &_File::is_open); - ClassDB::bind_method(D_METHOD("seek", "position"), &_File::seek); - ClassDB::bind_method(D_METHOD("seek_end", "position"), &_File::seek_end, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("get_position"), &_File::get_position); - ClassDB::bind_method(D_METHOD("get_length"), &_File::get_length); - ClassDB::bind_method(D_METHOD("eof_reached"), &_File::eof_reached); - ClassDB::bind_method(D_METHOD("get_8"), &_File::get_8); - ClassDB::bind_method(D_METHOD("get_16"), &_File::get_16); - ClassDB::bind_method(D_METHOD("get_32"), &_File::get_32); - ClassDB::bind_method(D_METHOD("get_64"), &_File::get_64); - ClassDB::bind_method(D_METHOD("get_float"), &_File::get_float); - ClassDB::bind_method(D_METHOD("get_double"), &_File::get_double); - ClassDB::bind_method(D_METHOD("get_real"), &_File::get_real); - ClassDB::bind_method(D_METHOD("get_buffer", "length"), &_File::get_buffer); - ClassDB::bind_method(D_METHOD("get_line"), &_File::get_line); - ClassDB::bind_method(D_METHOD("get_csv_line", "delim"), &_File::get_csv_line, DEFVAL(",")); - ClassDB::bind_method(D_METHOD("get_as_text"), &_File::get_as_text); - ClassDB::bind_method(D_METHOD("get_md5", "path"), &_File::get_md5); - ClassDB::bind_method(D_METHOD("get_sha256", "path"), &_File::get_sha256); - ClassDB::bind_method(D_METHOD("is_big_endian"), &_File::is_big_endian); - ClassDB::bind_method(D_METHOD("set_big_endian", "big_endian"), &_File::set_big_endian); - ClassDB::bind_method(D_METHOD("get_error"), &_File::get_error); - ClassDB::bind_method(D_METHOD("get_var", "allow_objects"), &_File::get_var, DEFVAL(false)); - - ClassDB::bind_method(D_METHOD("store_8", "value"), &_File::store_8); - ClassDB::bind_method(D_METHOD("store_16", "value"), &_File::store_16); - ClassDB::bind_method(D_METHOD("store_32", "value"), &_File::store_32); - ClassDB::bind_method(D_METHOD("store_64", "value"), &_File::store_64); - ClassDB::bind_method(D_METHOD("store_float", "value"), &_File::store_float); - ClassDB::bind_method(D_METHOD("store_double", "value"), &_File::store_double); - ClassDB::bind_method(D_METHOD("store_real", "value"), &_File::store_real); - ClassDB::bind_method(D_METHOD("store_buffer", "buffer"), &_File::store_buffer); - ClassDB::bind_method(D_METHOD("store_line", "line"), &_File::store_line); - ClassDB::bind_method(D_METHOD("store_csv_line", "values", "delim"), &_File::store_csv_line, DEFVAL(",")); - ClassDB::bind_method(D_METHOD("store_string", "string"), &_File::store_string); - ClassDB::bind_method(D_METHOD("store_var", "value", "full_objects"), &_File::store_var, DEFVAL(false)); - - ClassDB::bind_method(D_METHOD("store_pascal_string", "string"), &_File::store_pascal_string); - ClassDB::bind_method(D_METHOD("get_pascal_string"), &_File::get_pascal_string); - - ClassDB::bind_method(D_METHOD("file_exists", "path"), &_File::file_exists); - ClassDB::bind_method(D_METHOD("get_modified_time", "file"), &_File::get_modified_time); +void File::_bind_methods() { + ClassDB::bind_method(D_METHOD("open_encrypted", "path", "mode_flags", "key"), &File::open_encrypted); + ClassDB::bind_method(D_METHOD("open_encrypted_with_pass", "path", "mode_flags", "pass"), &File::open_encrypted_pass); + ClassDB::bind_method(D_METHOD("open_compressed", "path", "mode_flags", "compression_mode"), &File::open_compressed, DEFVAL(0)); + + ClassDB::bind_method(D_METHOD("open", "path", "flags"), &File::open); + ClassDB::bind_method(D_METHOD("flush"), &File::flush); + ClassDB::bind_method(D_METHOD("close"), &File::close); + ClassDB::bind_method(D_METHOD("get_path"), &File::get_path); + ClassDB::bind_method(D_METHOD("get_path_absolute"), &File::get_path_absolute); + ClassDB::bind_method(D_METHOD("is_open"), &File::is_open); + ClassDB::bind_method(D_METHOD("seek", "position"), &File::seek); + ClassDB::bind_method(D_METHOD("seek_end", "position"), &File::seek_end, DEFVAL(0)); + ClassDB::bind_method(D_METHOD("get_position"), &File::get_position); + ClassDB::bind_method(D_METHOD("get_length"), &File::get_length); + ClassDB::bind_method(D_METHOD("eof_reached"), &File::eof_reached); + ClassDB::bind_method(D_METHOD("get_8"), &File::get_8); + ClassDB::bind_method(D_METHOD("get_16"), &File::get_16); + ClassDB::bind_method(D_METHOD("get_32"), &File::get_32); + ClassDB::bind_method(D_METHOD("get_64"), &File::get_64); + ClassDB::bind_method(D_METHOD("get_float"), &File::get_float); + ClassDB::bind_method(D_METHOD("get_double"), &File::get_double); + ClassDB::bind_method(D_METHOD("get_real"), &File::get_real); + ClassDB::bind_method(D_METHOD("get_buffer", "length"), &File::get_buffer); + ClassDB::bind_method(D_METHOD("get_line"), &File::get_line); + ClassDB::bind_method(D_METHOD("get_csv_line", "delim"), &File::get_csv_line, DEFVAL(",")); + ClassDB::bind_method(D_METHOD("get_as_text"), &File::get_as_text); + ClassDB::bind_method(D_METHOD("get_md5", "path"), &File::get_md5); + ClassDB::bind_method(D_METHOD("get_sha256", "path"), &File::get_sha256); + ClassDB::bind_method(D_METHOD("is_big_endian"), &File::is_big_endian); + ClassDB::bind_method(D_METHOD("set_big_endian", "big_endian"), &File::set_big_endian); + ClassDB::bind_method(D_METHOD("get_error"), &File::get_error); + ClassDB::bind_method(D_METHOD("get_var", "allow_objects"), &File::get_var, DEFVAL(false)); + + ClassDB::bind_method(D_METHOD("store_8", "value"), &File::store_8); + ClassDB::bind_method(D_METHOD("store_16", "value"), &File::store_16); + ClassDB::bind_method(D_METHOD("store_32", "value"), &File::store_32); + ClassDB::bind_method(D_METHOD("store_64", "value"), &File::store_64); + ClassDB::bind_method(D_METHOD("store_float", "value"), &File::store_float); + ClassDB::bind_method(D_METHOD("store_double", "value"), &File::store_double); + ClassDB::bind_method(D_METHOD("store_real", "value"), &File::store_real); + ClassDB::bind_method(D_METHOD("store_buffer", "buffer"), &File::store_buffer); + ClassDB::bind_method(D_METHOD("store_line", "line"), &File::store_line); + ClassDB::bind_method(D_METHOD("store_csv_line", "values", "delim"), &File::store_csv_line, DEFVAL(",")); + ClassDB::bind_method(D_METHOD("store_string", "string"), &File::store_string); + ClassDB::bind_method(D_METHOD("store_var", "value", "full_objects"), &File::store_var, DEFVAL(false)); + + ClassDB::bind_method(D_METHOD("store_pascal_string", "string"), &File::store_pascal_string); + ClassDB::bind_method(D_METHOD("get_pascal_string"), &File::get_pascal_string); + + ClassDB::bind_method(D_METHOD("file_exists", "path"), &File::file_exists); + ClassDB::bind_method(D_METHOD("get_modified_time", "file"), &File::get_modified_time); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "big_endian"), "set_big_endian", "is_big_endian"); @@ -1411,15 +1413,15 @@ void _File::_bind_methods() { BIND_ENUM_CONSTANT(COMPRESSION_GZIP); } -_File::~_File() { +File::~File() { if (f) { memdelete(f); } } -////// _Directory ////// +////// Directory ////// -Error _Directory::open(const String &p_path) { +Error Directory::open(const String &p_path) { Error err; DirAccess *alt = DirAccess::open(p_path, &err); @@ -1435,11 +1437,11 @@ Error _Directory::open(const String &p_path) { return OK; } -bool _Directory::is_open() const { +bool Directory::is_open() const { return d && dir_open; } -Error _Directory::list_dir_begin(bool p_show_navigational, bool p_show_hidden) { +Error Directory::list_dir_begin(bool p_show_navigational, bool p_show_hidden) { ERR_FAIL_COND_V_MSG(!is_open(), ERR_UNCONFIGURED, "Directory must be opened before use."); _list_skip_navigational = !p_show_navigational; @@ -1448,7 +1450,7 @@ Error _Directory::list_dir_begin(bool p_show_navigational, bool p_show_hidden) { return d->list_dir_begin(); } -String _Directory::get_next() { +String Directory::get_next() { ERR_FAIL_COND_V_MSG(!is_open(), "", "Directory must be opened before use."); String next = d->get_next(); @@ -1458,32 +1460,32 @@ String _Directory::get_next() { return next; } -bool _Directory::current_is_dir() const { +bool Directory::current_is_dir() const { ERR_FAIL_COND_V_MSG(!is_open(), false, "Directory must be opened before use."); return d->current_is_dir(); } -void _Directory::list_dir_end() { +void Directory::list_dir_end() { ERR_FAIL_COND_MSG(!is_open(), "Directory must be opened before use."); d->list_dir_end(); } -int _Directory::get_drive_count() { +int Directory::get_drive_count() { ERR_FAIL_COND_V_MSG(!is_open(), 0, "Directory must be opened before use."); return d->get_drive_count(); } -String _Directory::get_drive(int p_drive) { +String Directory::get_drive(int p_drive) { ERR_FAIL_COND_V_MSG(!is_open(), "", "Directory must be opened before use."); return d->get_drive(p_drive); } -int _Directory::get_current_drive() { +int Directory::get_current_drive() { ERR_FAIL_COND_V_MSG(!is_open(), 0, "Directory must be opened before use."); return d->get_current_drive(); } -Error _Directory::change_dir(String p_dir) { +Error Directory::change_dir(String p_dir) { ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory is not configured properly."); Error err = d->change_dir(p_dir); @@ -1495,12 +1497,12 @@ Error _Directory::change_dir(String p_dir) { return OK; } -String _Directory::get_current_dir() { +String Directory::get_current_dir() { ERR_FAIL_COND_V_MSG(!is_open(), "", "Directory must be opened before use."); return d->get_current_dir(); } -Error _Directory::make_dir(String p_dir) { +Error Directory::make_dir(String p_dir) { ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory is not configured properly."); if (!p_dir.is_rel_path()) { DirAccess *d = DirAccess::create_for_path(p_dir); @@ -1511,7 +1513,7 @@ Error _Directory::make_dir(String p_dir) { return d->make_dir(p_dir); } -Error _Directory::make_dir_recursive(String p_dir) { +Error Directory::make_dir_recursive(String p_dir) { ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory is not configured properly."); if (!p_dir.is_rel_path()) { DirAccess *d = DirAccess::create_for_path(p_dir); @@ -1522,7 +1524,7 @@ Error _Directory::make_dir_recursive(String p_dir) { return d->make_dir_recursive(p_dir); } -bool _Directory::file_exists(String p_file) { +bool Directory::file_exists(String p_file) { ERR_FAIL_COND_V_MSG(!d, false, "Directory is not configured properly."); if (!p_file.is_rel_path()) { return FileAccess::exists(p_file); @@ -1531,7 +1533,7 @@ bool _Directory::file_exists(String p_file) { return d->file_exists(p_file); } -bool _Directory::dir_exists(String p_dir) { +bool Directory::dir_exists(String p_dir) { ERR_FAIL_COND_V_MSG(!d, false, "Directory is not configured properly."); if (!p_dir.is_rel_path()) { DirAccess *d = DirAccess::create_for_path(p_dir); @@ -1543,17 +1545,17 @@ bool _Directory::dir_exists(String p_dir) { return d->dir_exists(p_dir); } -uint64_t _Directory::get_space_left() { +uint64_t Directory::get_space_left() { ERR_FAIL_COND_V_MSG(!d, 0, "Directory must be opened before use."); return d->get_space_left() / 1024 * 1024; // Truncate to closest MiB. } -Error _Directory::copy(String p_from, String p_to) { +Error Directory::copy(String p_from, String p_to) { ERR_FAIL_COND_V_MSG(!is_open(), ERR_UNCONFIGURED, "Directory must be opened before use."); return d->copy(p_from, p_to); } -Error _Directory::rename(String p_from, String p_to) { +Error Directory::rename(String p_from, String p_to) { ERR_FAIL_COND_V_MSG(!is_open(), ERR_UNCONFIGURED, "Directory must be opened before use."); ERR_FAIL_COND_V_MSG(p_from.is_empty() || p_from == "." || p_from == "..", ERR_INVALID_PARAMETER, "Invalid path to rename."); @@ -1569,7 +1571,7 @@ Error _Directory::rename(String p_from, String p_to) { return d->rename(p_from, p_to); } -Error _Directory::remove(String p_name) { +Error Directory::remove(String p_name) { ERR_FAIL_COND_V_MSG(!is_open(), ERR_UNCONFIGURED, "Directory must be opened before use."); if (!p_name.is_rel_path()) { DirAccess *d = DirAccess::create_for_path(p_name); @@ -1581,47 +1583,47 @@ Error _Directory::remove(String p_name) { return d->remove(p_name); } -void _Directory::_bind_methods() { - ClassDB::bind_method(D_METHOD("open", "path"), &_Directory::open); - ClassDB::bind_method(D_METHOD("list_dir_begin", "show_navigational", "show_hidden"), &_Directory::list_dir_begin, DEFVAL(false), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("get_next"), &_Directory::get_next); - ClassDB::bind_method(D_METHOD("current_is_dir"), &_Directory::current_is_dir); - ClassDB::bind_method(D_METHOD("list_dir_end"), &_Directory::list_dir_end); - ClassDB::bind_method(D_METHOD("get_drive_count"), &_Directory::get_drive_count); - ClassDB::bind_method(D_METHOD("get_drive", "idx"), &_Directory::get_drive); - ClassDB::bind_method(D_METHOD("get_current_drive"), &_Directory::get_current_drive); - ClassDB::bind_method(D_METHOD("change_dir", "todir"), &_Directory::change_dir); - ClassDB::bind_method(D_METHOD("get_current_dir"), &_Directory::get_current_dir); - ClassDB::bind_method(D_METHOD("make_dir", "path"), &_Directory::make_dir); - ClassDB::bind_method(D_METHOD("make_dir_recursive", "path"), &_Directory::make_dir_recursive); - ClassDB::bind_method(D_METHOD("file_exists", "path"), &_Directory::file_exists); - ClassDB::bind_method(D_METHOD("dir_exists", "path"), &_Directory::dir_exists); - //ClassDB::bind_method(D_METHOD("get_modified_time","file"),&_Directory::get_modified_time); - ClassDB::bind_method(D_METHOD("get_space_left"), &_Directory::get_space_left); - ClassDB::bind_method(D_METHOD("copy", "from", "to"), &_Directory::copy); - ClassDB::bind_method(D_METHOD("rename", "from", "to"), &_Directory::rename); - ClassDB::bind_method(D_METHOD("remove", "path"), &_Directory::remove); -} - -_Directory::_Directory() { +void Directory::_bind_methods() { + ClassDB::bind_method(D_METHOD("open", "path"), &Directory::open); + ClassDB::bind_method(D_METHOD("list_dir_begin", "show_navigational", "show_hidden"), &Directory::list_dir_begin, DEFVAL(false), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("get_next"), &Directory::get_next); + ClassDB::bind_method(D_METHOD("current_is_dir"), &Directory::current_is_dir); + ClassDB::bind_method(D_METHOD("list_dir_end"), &Directory::list_dir_end); + ClassDB::bind_method(D_METHOD("get_drive_count"), &Directory::get_drive_count); + ClassDB::bind_method(D_METHOD("get_drive", "idx"), &Directory::get_drive); + ClassDB::bind_method(D_METHOD("get_current_drive"), &Directory::get_current_drive); + ClassDB::bind_method(D_METHOD("change_dir", "todir"), &Directory::change_dir); + ClassDB::bind_method(D_METHOD("get_current_dir"), &Directory::get_current_dir); + ClassDB::bind_method(D_METHOD("make_dir", "path"), &Directory::make_dir); + ClassDB::bind_method(D_METHOD("make_dir_recursive", "path"), &Directory::make_dir_recursive); + ClassDB::bind_method(D_METHOD("file_exists", "path"), &Directory::file_exists); + ClassDB::bind_method(D_METHOD("dir_exists", "path"), &Directory::dir_exists); + //ClassDB::bind_method(D_METHOD("get_modified_time","file"),&Directory::get_modified_time); + ClassDB::bind_method(D_METHOD("get_space_left"), &Directory::get_space_left); + ClassDB::bind_method(D_METHOD("copy", "from", "to"), &Directory::copy); + ClassDB::bind_method(D_METHOD("rename", "from", "to"), &Directory::rename); + ClassDB::bind_method(D_METHOD("remove", "path"), &Directory::remove); +} + +Directory::Directory() { d = DirAccess::create(DirAccess::ACCESS_RESOURCES); } -_Directory::~_Directory() { +Directory::~Directory() { if (d) { memdelete(d); } } -////// _Marshalls ////// +////// Marshalls ////// -_Marshalls *_Marshalls::singleton = nullptr; +Marshalls *Marshalls::singleton = nullptr; -_Marshalls *_Marshalls::get_singleton() { +Marshalls *Marshalls::get_singleton() { return singleton; } -String _Marshalls::variant_to_base64(const Variant &p_var, bool p_full_objects) { +String Marshalls::variant_to_base64(const Variant &p_var, bool p_full_objects) { int len; Error err = encode_variant(p_var, nullptr, len, p_full_objects); ERR_FAIL_COND_V_MSG(err != OK, "", "Error when trying to encode Variant."); @@ -1639,7 +1641,7 @@ String _Marshalls::variant_to_base64(const Variant &p_var, bool p_full_objects) return ret; } -Variant _Marshalls::base64_to_variant(const String &p_str, bool p_allow_objects) { +Variant Marshalls::base64_to_variant(const String &p_str, bool p_allow_objects) { int strlen = p_str.length(); CharString cstr = p_str.ascii(); @@ -1657,13 +1659,13 @@ Variant _Marshalls::base64_to_variant(const String &p_str, bool p_allow_objects) return v; } -String _Marshalls::raw_to_base64(const Vector<uint8_t> &p_arr) { +String Marshalls::raw_to_base64(const Vector<uint8_t> &p_arr) { String ret = CryptoCore::b64_encode_str(p_arr.ptr(), p_arr.size()); ERR_FAIL_COND_V(ret == "", ret); return ret; } -Vector<uint8_t> _Marshalls::base64_to_raw(const String &p_str) { +Vector<uint8_t> Marshalls::base64_to_raw(const String &p_str) { int strlen = p_str.length(); CharString cstr = p_str.ascii(); @@ -1680,14 +1682,14 @@ Vector<uint8_t> _Marshalls::base64_to_raw(const String &p_str) { return buf; } -String _Marshalls::utf8_to_base64(const String &p_str) { +String Marshalls::utf8_to_base64(const String &p_str) { CharString cstr = p_str.utf8(); String ret = CryptoCore::b64_encode_str((unsigned char *)cstr.get_data(), cstr.length()); ERR_FAIL_COND_V(ret == "", ret); return ret; } -String _Marshalls::base64_to_utf8(const String &p_str) { +String Marshalls::base64_to_utf8(const String &p_str) { int strlen = p_str.length(); CharString cstr = p_str.ascii(); @@ -1704,62 +1706,62 @@ String _Marshalls::base64_to_utf8(const String &p_str) { return ret; } -void _Marshalls::_bind_methods() { - ClassDB::bind_method(D_METHOD("variant_to_base64", "variant", "full_objects"), &_Marshalls::variant_to_base64, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("base64_to_variant", "base64_str", "allow_objects"), &_Marshalls::base64_to_variant, DEFVAL(false)); +void Marshalls::_bind_methods() { + ClassDB::bind_method(D_METHOD("variant_to_base64", "variant", "full_objects"), &Marshalls::variant_to_base64, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("base64_to_variant", "base64_str", "allow_objects"), &Marshalls::base64_to_variant, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("raw_to_base64", "array"), &_Marshalls::raw_to_base64); - ClassDB::bind_method(D_METHOD("base64_to_raw", "base64_str"), &_Marshalls::base64_to_raw); + ClassDB::bind_method(D_METHOD("raw_to_base64", "array"), &Marshalls::raw_to_base64); + ClassDB::bind_method(D_METHOD("base64_to_raw", "base64_str"), &Marshalls::base64_to_raw); - ClassDB::bind_method(D_METHOD("utf8_to_base64", "utf8_str"), &_Marshalls::utf8_to_base64); - ClassDB::bind_method(D_METHOD("base64_to_utf8", "base64_str"), &_Marshalls::base64_to_utf8); + ClassDB::bind_method(D_METHOD("utf8_to_base64", "utf8_str"), &Marshalls::utf8_to_base64); + ClassDB::bind_method(D_METHOD("base64_to_utf8", "base64_str"), &Marshalls::base64_to_utf8); } -////// _Semaphore ////// +////// Semaphore ////// -void _Semaphore::wait() { +void Semaphore::wait() { semaphore.wait(); } -Error _Semaphore::try_wait() { +Error Semaphore::try_wait() { return semaphore.try_wait() ? OK : ERR_BUSY; } -void _Semaphore::post() { +void Semaphore::post() { semaphore.post(); } -void _Semaphore::_bind_methods() { - ClassDB::bind_method(D_METHOD("wait"), &_Semaphore::wait); - ClassDB::bind_method(D_METHOD("try_wait"), &_Semaphore::try_wait); - ClassDB::bind_method(D_METHOD("post"), &_Semaphore::post); +void Semaphore::_bind_methods() { + ClassDB::bind_method(D_METHOD("wait"), &Semaphore::wait); + ClassDB::bind_method(D_METHOD("try_wait"), &Semaphore::try_wait); + ClassDB::bind_method(D_METHOD("post"), &Semaphore::post); } -////// _Mutex ////// +////// Mutex ////// -void _Mutex::lock() { +void Mutex::lock() { mutex.lock(); } -Error _Mutex::try_lock() { +Error Mutex::try_lock() { return mutex.try_lock(); } -void _Mutex::unlock() { +void Mutex::unlock() { mutex.unlock(); } -void _Mutex::_bind_methods() { - ClassDB::bind_method(D_METHOD("lock"), &_Mutex::lock); - ClassDB::bind_method(D_METHOD("try_lock"), &_Mutex::try_lock); - ClassDB::bind_method(D_METHOD("unlock"), &_Mutex::unlock); +void Mutex::_bind_methods() { + ClassDB::bind_method(D_METHOD("lock"), &Mutex::lock); + ClassDB::bind_method(D_METHOD("try_lock"), &Mutex::try_lock); + ClassDB::bind_method(D_METHOD("unlock"), &Mutex::unlock); } -////// _Thread ////// +////// Thread ////// -void _Thread::_start_func(void *ud) { - Ref<_Thread> *tud = (Ref<_Thread> *)ud; - Ref<_Thread> t = *tud; +void Thread::_start_func(void *ud) { + Ref<Thread> *tud = (Ref<Thread> *)ud; + Ref<Thread> t = *tud; memdelete(tud); Callable::CallError ce; const Variant *arg[1] = { &t->userdata }; @@ -1794,7 +1796,7 @@ void _Thread::_start_func(void *ud) { } } - Thread::set_name(t->target_method); + ::Thread::set_name(t->target_method); t->ret = t->target_instance->call(t->target_method, arg, argc, ce); if (ce.error != Callable::CallError::CALL_OK) { @@ -1820,7 +1822,7 @@ void _Thread::_start_func(void *ud) { } } -Error _Thread::start(Object *p_instance, const StringName &p_method, const Variant &p_userdata, Priority p_priority) { +Error Thread::start(Object *p_instance, const StringName &p_method, const Variant &p_userdata, Priority p_priority) { ERR_FAIL_COND_V_MSG(active.is_set(), ERR_ALREADY_IN_USE, "Thread already started."); ERR_FAIL_COND_V(!p_instance, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(p_method == StringName(), ERR_INVALID_PARAMETER); @@ -1832,24 +1834,24 @@ Error _Thread::start(Object *p_instance, const StringName &p_method, const Varia userdata = p_userdata; active.set(); - Ref<_Thread> *ud = memnew(Ref<_Thread>(this)); + Ref<Thread> *ud = memnew(Ref<Thread>(this)); - Thread::Settings s; - s.priority = (Thread::Priority)p_priority; + ::Thread::Settings s; + s.priority = (::Thread::Priority)p_priority; thread.start(_start_func, ud, s); return OK; } -String _Thread::get_id() const { +String Thread::get_id() const { return itos(thread.get_id()); } -bool _Thread::is_active() const { +bool Thread::is_active() const { return active.is_set(); } -Variant _Thread::wait_to_finish() { +Variant Thread::wait_to_finish() { ERR_FAIL_COND_V_MSG(!active.is_set(), Variant(), "Thread must be active to wait for its completion."); thread.wait_to_finish(); Variant r = ret; @@ -1861,22 +1863,24 @@ Variant _Thread::wait_to_finish() { return r; } -void _Thread::_bind_methods() { - ClassDB::bind_method(D_METHOD("start", "instance", "method", "userdata", "priority"), &_Thread::start, DEFVAL(Variant()), DEFVAL(PRIORITY_NORMAL)); - ClassDB::bind_method(D_METHOD("get_id"), &_Thread::get_id); - ClassDB::bind_method(D_METHOD("is_active"), &_Thread::is_active); - ClassDB::bind_method(D_METHOD("wait_to_finish"), &_Thread::wait_to_finish); +void Thread::_bind_methods() { + ClassDB::bind_method(D_METHOD("start", "instance", "method", "userdata", "priority"), &Thread::start, DEFVAL(Variant()), DEFVAL(PRIORITY_NORMAL)); + ClassDB::bind_method(D_METHOD("get_id"), &Thread::get_id); + ClassDB::bind_method(D_METHOD("is_active"), &Thread::is_active); + ClassDB::bind_method(D_METHOD("wait_to_finish"), &Thread::wait_to_finish); BIND_ENUM_CONSTANT(PRIORITY_LOW); BIND_ENUM_CONSTANT(PRIORITY_NORMAL); BIND_ENUM_CONSTANT(PRIORITY_HIGH); } -////// _ClassDB ////// +namespace special { + +////// ClassDB ////// -PackedStringArray _ClassDB::get_class_list() const { +PackedStringArray ClassDB::get_class_list() const { List<StringName> classes; - ClassDB::get_class_list(&classes); + ::ClassDB::get_class_list(&classes); PackedStringArray ret; ret.resize(classes.size()); @@ -1888,9 +1892,9 @@ PackedStringArray _ClassDB::get_class_list() const { return ret; } -PackedStringArray _ClassDB::get_inheriters_from_class(const StringName &p_class) const { +PackedStringArray ClassDB::get_inheriters_from_class(const StringName &p_class) const { List<StringName> classes; - ClassDB::get_inheriters_from_class(p_class, &classes); + ::ClassDB::get_inheriters_from_class(p_class, &classes); PackedStringArray ret; ret.resize(classes.size()); @@ -1902,24 +1906,24 @@ PackedStringArray _ClassDB::get_inheriters_from_class(const StringName &p_class) return ret; } -StringName _ClassDB::get_parent_class(const StringName &p_class) const { - return ClassDB::get_parent_class(p_class); +StringName ClassDB::get_parent_class(const StringName &p_class) const { + return ::ClassDB::get_parent_class(p_class); } -bool _ClassDB::class_exists(const StringName &p_class) const { - return ClassDB::class_exists(p_class); +bool ClassDB::class_exists(const StringName &p_class) const { + return ::ClassDB::class_exists(p_class); } -bool _ClassDB::is_parent_class(const StringName &p_class, const StringName &p_inherits) const { - return ClassDB::is_parent_class(p_class, p_inherits); +bool ClassDB::is_parent_class(const StringName &p_class, const StringName &p_inherits) const { + return ::ClassDB::is_parent_class(p_class, p_inherits); } -bool _ClassDB::can_instantiate(const StringName &p_class) const { - return ClassDB::can_instantiate(p_class); +bool ClassDB::can_instantiate(const StringName &p_class) const { + return ::ClassDB::can_instantiate(p_class); } -Variant _ClassDB::instantiate(const StringName &p_class) const { - Object *obj = ClassDB::instantiate(p_class); +Variant ClassDB::instantiate(const StringName &p_class) const { + Object *obj = ::ClassDB::instantiate(p_class); if (!obj) { return Variant(); } @@ -1932,22 +1936,22 @@ Variant _ClassDB::instantiate(const StringName &p_class) const { } } -bool _ClassDB::has_signal(StringName p_class, StringName p_signal) const { - return ClassDB::has_signal(p_class, p_signal); +bool ClassDB::has_signal(StringName p_class, StringName p_signal) const { + return ::ClassDB::has_signal(p_class, p_signal); } -Dictionary _ClassDB::get_signal(StringName p_class, StringName p_signal) const { +Dictionary ClassDB::get_signal(StringName p_class, StringName p_signal) const { MethodInfo signal; - if (ClassDB::get_signal(p_class, p_signal, &signal)) { + if (::ClassDB::get_signal(p_class, p_signal, &signal)) { return signal.operator Dictionary(); } else { return Dictionary(); } } -Array _ClassDB::get_signal_list(StringName p_class, bool p_no_inheritance) const { +Array ClassDB::get_signal_list(StringName p_class, bool p_no_inheritance) const { List<MethodInfo> signals; - ClassDB::get_signal_list(p_class, &signals, p_no_inheritance); + ::ClassDB::get_signal_list(p_class, &signals, p_no_inheritance); Array ret; for (const MethodInfo &E : signals) { @@ -1957,9 +1961,9 @@ Array _ClassDB::get_signal_list(StringName p_class, bool p_no_inheritance) const return ret; } -Array _ClassDB::get_property_list(StringName p_class, bool p_no_inheritance) const { +Array ClassDB::get_property_list(StringName p_class, bool p_no_inheritance) const { List<PropertyInfo> plist; - ClassDB::get_property_list(p_class, &plist, p_no_inheritance); + ::ClassDB::get_property_list(p_class, &plist, p_no_inheritance); Array ret; for (const PropertyInfo &E : plist) { ret.push_back(E.operator Dictionary()); @@ -1968,16 +1972,16 @@ Array _ClassDB::get_property_list(StringName p_class, bool p_no_inheritance) con return ret; } -Variant _ClassDB::get_property(Object *p_object, const StringName &p_property) const { +Variant ClassDB::get_property(Object *p_object, const StringName &p_property) const { Variant ret; - ClassDB::get_property(p_object, p_property, ret); + ::ClassDB::get_property(p_object, p_property, ret); return ret; } -Error _ClassDB::set_property(Object *p_object, const StringName &p_property, const Variant &p_value) const { +Error ClassDB::set_property(Object *p_object, const StringName &p_property, const Variant &p_value) const { Variant ret; bool valid; - if (!ClassDB::set_property(p_object, p_property, p_value, &valid)) { + if (!::ClassDB::set_property(p_object, p_property, p_value, &valid)) { return ERR_UNAVAILABLE; } else if (!valid) { return ERR_INVALID_DATA; @@ -1985,13 +1989,13 @@ Error _ClassDB::set_property(Object *p_object, const StringName &p_property, con return OK; } -bool _ClassDB::has_method(StringName p_class, StringName p_method, bool p_no_inheritance) const { - return ClassDB::has_method(p_class, p_method, p_no_inheritance); +bool ClassDB::has_method(StringName p_class, StringName p_method, bool p_no_inheritance) const { + return ::ClassDB::has_method(p_class, p_method, p_no_inheritance); } -Array _ClassDB::get_method_list(StringName p_class, bool p_no_inheritance) const { +Array ClassDB::get_method_list(StringName p_class, bool p_no_inheritance) const { List<MethodInfo> methods; - ClassDB::get_method_list(p_class, &methods, p_no_inheritance); + ::ClassDB::get_method_list(p_class, &methods, p_no_inheritance); Array ret; for (const MethodInfo &E : methods) { @@ -2007,9 +2011,9 @@ Array _ClassDB::get_method_list(StringName p_class, bool p_no_inheritance) const return ret; } -PackedStringArray _ClassDB::get_integer_constant_list(const StringName &p_class, bool p_no_inheritance) const { +PackedStringArray ClassDB::get_integer_constant_list(const StringName &p_class, bool p_no_inheritance) const { List<String> constants; - ClassDB::get_integer_constant_list(p_class, &constants, p_no_inheritance); + ::ClassDB::get_integer_constant_list(p_class, &constants, p_no_inheritance); PackedStringArray ret; ret.resize(constants.size()); @@ -2021,204 +2025,206 @@ PackedStringArray _ClassDB::get_integer_constant_list(const StringName &p_class, return ret; } -bool _ClassDB::has_integer_constant(const StringName &p_class, const StringName &p_name) const { +bool ClassDB::has_integer_constant(const StringName &p_class, const StringName &p_name) const { bool success; - ClassDB::get_integer_constant(p_class, p_name, &success); + ::ClassDB::get_integer_constant(p_class, p_name, &success); return success; } -int _ClassDB::get_integer_constant(const StringName &p_class, const StringName &p_name) const { +int ClassDB::get_integer_constant(const StringName &p_class, const StringName &p_name) const { bool found; - int c = ClassDB::get_integer_constant(p_class, p_name, &found); + int c = ::ClassDB::get_integer_constant(p_class, p_name, &found); ERR_FAIL_COND_V(!found, 0); return c; } -StringName _ClassDB::get_category(const StringName &p_node) const { - return ClassDB::get_category(p_node); +StringName ClassDB::get_category(const StringName &p_node) const { + return ::ClassDB::get_category(p_node); } -bool _ClassDB::is_class_enabled(StringName p_class) const { - return ClassDB::is_class_enabled(p_class); +bool ClassDB::is_class_enabled(StringName p_class) const { + return ::ClassDB::is_class_enabled(p_class); } -void _ClassDB::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_class_list"), &_ClassDB::get_class_list); - ClassDB::bind_method(D_METHOD("get_inheriters_from_class", "class"), &_ClassDB::get_inheriters_from_class); - ClassDB::bind_method(D_METHOD("get_parent_class", "class"), &_ClassDB::get_parent_class); - ClassDB::bind_method(D_METHOD("class_exists", "class"), &_ClassDB::class_exists); - ClassDB::bind_method(D_METHOD("is_parent_class", "class", "inherits"), &_ClassDB::is_parent_class); - ClassDB::bind_method(D_METHOD("can_instantiate", "class"), &_ClassDB::can_instantiate); - ClassDB::bind_method(D_METHOD("instantiate", "class"), &_ClassDB::instantiate); +void ClassDB::_bind_methods() { + ::ClassDB::bind_method(D_METHOD("get_class_list"), &ClassDB::get_class_list); + ::ClassDB::bind_method(D_METHOD("get_inheriters_from_class", "class"), &ClassDB::get_inheriters_from_class); + ::ClassDB::bind_method(D_METHOD("get_parent_class", "class"), &ClassDB::get_parent_class); + ::ClassDB::bind_method(D_METHOD("class_exists", "class"), &ClassDB::class_exists); + ::ClassDB::bind_method(D_METHOD("is_parent_class", "class", "inherits"), &ClassDB::is_parent_class); + ::ClassDB::bind_method(D_METHOD("can_instantiate", "class"), &ClassDB::can_instantiate); + ::ClassDB::bind_method(D_METHOD("instantiate", "class"), &ClassDB::instantiate); - ClassDB::bind_method(D_METHOD("class_has_signal", "class", "signal"), &_ClassDB::has_signal); - ClassDB::bind_method(D_METHOD("class_get_signal", "class", "signal"), &_ClassDB::get_signal); - ClassDB::bind_method(D_METHOD("class_get_signal_list", "class", "no_inheritance"), &_ClassDB::get_signal_list, DEFVAL(false)); + ::ClassDB::bind_method(D_METHOD("class_has_signal", "class", "signal"), &ClassDB::has_signal); + ::ClassDB::bind_method(D_METHOD("class_get_signal", "class", "signal"), &ClassDB::get_signal); + ::ClassDB::bind_method(D_METHOD("class_get_signal_list", "class", "no_inheritance"), &ClassDB::get_signal_list, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("class_get_property_list", "class", "no_inheritance"), &_ClassDB::get_property_list, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("class_get_property", "object", "property"), &_ClassDB::get_property); - ClassDB::bind_method(D_METHOD("class_set_property", "object", "property", "value"), &_ClassDB::set_property); + ::ClassDB::bind_method(D_METHOD("class_get_property_list", "class", "no_inheritance"), &ClassDB::get_property_list, DEFVAL(false)); + ::ClassDB::bind_method(D_METHOD("class_get_property", "object", "property"), &ClassDB::get_property); + ::ClassDB::bind_method(D_METHOD("class_set_property", "object", "property", "value"), &ClassDB::set_property); - ClassDB::bind_method(D_METHOD("class_has_method", "class", "method", "no_inheritance"), &_ClassDB::has_method, DEFVAL(false)); + ::ClassDB::bind_method(D_METHOD("class_has_method", "class", "method", "no_inheritance"), &ClassDB::has_method, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("class_get_method_list", "class", "no_inheritance"), &_ClassDB::get_method_list, DEFVAL(false)); + ::ClassDB::bind_method(D_METHOD("class_get_method_list", "class", "no_inheritance"), &ClassDB::get_method_list, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("class_get_integer_constant_list", "class", "no_inheritance"), &_ClassDB::get_integer_constant_list, DEFVAL(false)); + ::ClassDB::bind_method(D_METHOD("class_get_integer_constant_list", "class", "no_inheritance"), &ClassDB::get_integer_constant_list, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("class_has_integer_constant", "class", "name"), &_ClassDB::has_integer_constant); - ClassDB::bind_method(D_METHOD("class_get_integer_constant", "class", "name"), &_ClassDB::get_integer_constant); + ::ClassDB::bind_method(D_METHOD("class_has_integer_constant", "class", "name"), &ClassDB::has_integer_constant); + ::ClassDB::bind_method(D_METHOD("class_get_integer_constant", "class", "name"), &ClassDB::get_integer_constant); - ClassDB::bind_method(D_METHOD("class_get_category", "class"), &_ClassDB::get_category); - ClassDB::bind_method(D_METHOD("is_class_enabled", "class"), &_ClassDB::is_class_enabled); + ::ClassDB::bind_method(D_METHOD("class_get_category", "class"), &ClassDB::get_category); + ::ClassDB::bind_method(D_METHOD("is_class_enabled", "class"), &ClassDB::is_class_enabled); } -////// _Engine ////// +} // namespace special -void _Engine::set_physics_ticks_per_second(int p_ips) { - Engine::get_singleton()->set_physics_ticks_per_second(p_ips); +////// Engine ////// + +void Engine::set_physics_ticks_per_second(int p_ips) { + ::Engine::get_singleton()->set_physics_ticks_per_second(p_ips); } -int _Engine::get_physics_ticks_per_second() const { - return Engine::get_singleton()->get_physics_ticks_per_second(); +int Engine::get_physics_ticks_per_second() const { + return ::Engine::get_singleton()->get_physics_ticks_per_second(); } -void _Engine::set_physics_jitter_fix(double p_threshold) { - Engine::get_singleton()->set_physics_jitter_fix(p_threshold); +void Engine::set_physics_jitter_fix(double p_threshold) { + ::Engine::get_singleton()->set_physics_jitter_fix(p_threshold); } -double _Engine::get_physics_jitter_fix() const { - return Engine::get_singleton()->get_physics_jitter_fix(); +double Engine::get_physics_jitter_fix() const { + return ::Engine::get_singleton()->get_physics_jitter_fix(); } -double _Engine::get_physics_interpolation_fraction() const { - return Engine::get_singleton()->get_physics_interpolation_fraction(); +double Engine::get_physics_interpolation_fraction() const { + return ::Engine::get_singleton()->get_physics_interpolation_fraction(); } -void _Engine::set_target_fps(int p_fps) { - Engine::get_singleton()->set_target_fps(p_fps); +void Engine::set_target_fps(int p_fps) { + ::Engine::get_singleton()->set_target_fps(p_fps); } -int _Engine::get_target_fps() const { - return Engine::get_singleton()->get_target_fps(); +int Engine::get_target_fps() const { + return ::Engine::get_singleton()->get_target_fps(); } -double _Engine::get_frames_per_second() const { - return Engine::get_singleton()->get_frames_per_second(); +double Engine::get_frames_per_second() const { + return ::Engine::get_singleton()->get_frames_per_second(); } -uint64_t _Engine::get_physics_frames() const { - return Engine::get_singleton()->get_physics_frames(); +uint64_t Engine::get_physics_frames() const { + return ::Engine::get_singleton()->get_physics_frames(); } -uint64_t _Engine::get_process_frames() const { - return Engine::get_singleton()->get_process_frames(); +uint64_t Engine::get_process_frames() const { + return ::Engine::get_singleton()->get_process_frames(); } -void _Engine::set_time_scale(double p_scale) { - Engine::get_singleton()->set_time_scale(p_scale); +void Engine::set_time_scale(double p_scale) { + ::Engine::get_singleton()->set_time_scale(p_scale); } -double _Engine::get_time_scale() { - return Engine::get_singleton()->get_time_scale(); +double Engine::get_time_scale() { + return ::Engine::get_singleton()->get_time_scale(); } -int _Engine::get_frames_drawn() { - return Engine::get_singleton()->get_frames_drawn(); +int Engine::get_frames_drawn() { + return ::Engine::get_singleton()->get_frames_drawn(); } -MainLoop *_Engine::get_main_loop() const { - //needs to remain in OS, since it's actually OS that interacts with it, but it's better exposed here - return OS::get_singleton()->get_main_loop(); +MainLoop *Engine::get_main_loop() const { + // Needs to remain in OS, since it's actually OS that interacts with it, but it's better exposed here + return ::OS::get_singleton()->get_main_loop(); } -Dictionary _Engine::get_version_info() const { - return Engine::get_singleton()->get_version_info(); +Dictionary Engine::get_version_info() const { + return ::Engine::get_singleton()->get_version_info(); } -Dictionary _Engine::get_author_info() const { - return Engine::get_singleton()->get_author_info(); +Dictionary Engine::get_author_info() const { + return ::Engine::get_singleton()->get_author_info(); } -Array _Engine::get_copyright_info() const { - return Engine::get_singleton()->get_copyright_info(); +Array Engine::get_copyright_info() const { + return ::Engine::get_singleton()->get_copyright_info(); } -Dictionary _Engine::get_donor_info() const { - return Engine::get_singleton()->get_donor_info(); +Dictionary Engine::get_donor_info() const { + return ::Engine::get_singleton()->get_donor_info(); } -Dictionary _Engine::get_license_info() const { - return Engine::get_singleton()->get_license_info(); +Dictionary Engine::get_license_info() const { + return ::Engine::get_singleton()->get_license_info(); } -String _Engine::get_license_text() const { - return Engine::get_singleton()->get_license_text(); +String Engine::get_license_text() const { + return ::Engine::get_singleton()->get_license_text(); } -bool _Engine::is_in_physics_frame() const { - return Engine::get_singleton()->is_in_physics_frame(); +bool Engine::is_in_physics_frame() const { + return ::Engine::get_singleton()->is_in_physics_frame(); } -bool _Engine::has_singleton(const String &p_name) const { - return Engine::get_singleton()->has_singleton(p_name); +bool Engine::has_singleton(const String &p_name) const { + return ::Engine::get_singleton()->has_singleton(p_name); } -Object *_Engine::get_singleton_object(const String &p_name) const { - return Engine::get_singleton()->get_singleton_object(p_name); +Object *Engine::get_singleton_object(const String &p_name) const { + return ::Engine::get_singleton()->get_singleton_object(p_name); } -void _Engine::set_editor_hint(bool p_enabled) { - Engine::get_singleton()->set_editor_hint(p_enabled); +void Engine::set_editor_hint(bool p_enabled) { + ::Engine::get_singleton()->set_editor_hint(p_enabled); } -bool _Engine::is_editor_hint() const { - return Engine::get_singleton()->is_editor_hint(); +bool Engine::is_editor_hint() const { + return ::Engine::get_singleton()->is_editor_hint(); } -void _Engine::set_print_error_messages(bool p_enabled) { - Engine::get_singleton()->set_print_error_messages(p_enabled); +void Engine::set_print_error_messages(bool p_enabled) { + ::Engine::get_singleton()->set_print_error_messages(p_enabled); } -bool _Engine::is_printing_error_messages() const { - return Engine::get_singleton()->is_printing_error_messages(); +bool Engine::is_printing_error_messages() const { + return ::Engine::get_singleton()->is_printing_error_messages(); } -void _Engine::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_physics_ticks_per_second", "physics_ticks_per_second"), &_Engine::set_physics_ticks_per_second); - ClassDB::bind_method(D_METHOD("get_physics_ticks_per_second"), &_Engine::get_physics_ticks_per_second); - ClassDB::bind_method(D_METHOD("set_physics_jitter_fix", "physics_jitter_fix"), &_Engine::set_physics_jitter_fix); - ClassDB::bind_method(D_METHOD("get_physics_jitter_fix"), &_Engine::get_physics_jitter_fix); - ClassDB::bind_method(D_METHOD("get_physics_interpolation_fraction"), &_Engine::get_physics_interpolation_fraction); - ClassDB::bind_method(D_METHOD("set_target_fps", "target_fps"), &_Engine::set_target_fps); - ClassDB::bind_method(D_METHOD("get_target_fps"), &_Engine::get_target_fps); +void Engine::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_physics_ticks_per_second", "physics_ticks_per_second"), &Engine::set_physics_ticks_per_second); + ClassDB::bind_method(D_METHOD("get_physics_ticks_per_second"), &Engine::get_physics_ticks_per_second); + ClassDB::bind_method(D_METHOD("set_physics_jitter_fix", "physics_jitter_fix"), &Engine::set_physics_jitter_fix); + ClassDB::bind_method(D_METHOD("get_physics_jitter_fix"), &Engine::get_physics_jitter_fix); + ClassDB::bind_method(D_METHOD("get_physics_interpolation_fraction"), &Engine::get_physics_interpolation_fraction); + ClassDB::bind_method(D_METHOD("set_target_fps", "target_fps"), &Engine::set_target_fps); + ClassDB::bind_method(D_METHOD("get_target_fps"), &Engine::get_target_fps); - ClassDB::bind_method(D_METHOD("set_time_scale", "time_scale"), &_Engine::set_time_scale); - ClassDB::bind_method(D_METHOD("get_time_scale"), &_Engine::get_time_scale); + ClassDB::bind_method(D_METHOD("set_time_scale", "time_scale"), &Engine::set_time_scale); + ClassDB::bind_method(D_METHOD("get_time_scale"), &Engine::get_time_scale); - ClassDB::bind_method(D_METHOD("get_frames_drawn"), &_Engine::get_frames_drawn); - ClassDB::bind_method(D_METHOD("get_frames_per_second"), &_Engine::get_frames_per_second); - ClassDB::bind_method(D_METHOD("get_physics_frames"), &_Engine::get_physics_frames); - ClassDB::bind_method(D_METHOD("get_process_frames"), &_Engine::get_process_frames); + ClassDB::bind_method(D_METHOD("get_frames_drawn"), &Engine::get_frames_drawn); + ClassDB::bind_method(D_METHOD("get_frames_per_second"), &Engine::get_frames_per_second); + ClassDB::bind_method(D_METHOD("get_physics_frames"), &Engine::get_physics_frames); + ClassDB::bind_method(D_METHOD("get_process_frames"), &Engine::get_process_frames); - ClassDB::bind_method(D_METHOD("get_main_loop"), &_Engine::get_main_loop); + ClassDB::bind_method(D_METHOD("get_main_loop"), &Engine::get_main_loop); - ClassDB::bind_method(D_METHOD("get_version_info"), &_Engine::get_version_info); - ClassDB::bind_method(D_METHOD("get_author_info"), &_Engine::get_author_info); - ClassDB::bind_method(D_METHOD("get_copyright_info"), &_Engine::get_copyright_info); - ClassDB::bind_method(D_METHOD("get_donor_info"), &_Engine::get_donor_info); - ClassDB::bind_method(D_METHOD("get_license_info"), &_Engine::get_license_info); - ClassDB::bind_method(D_METHOD("get_license_text"), &_Engine::get_license_text); + ClassDB::bind_method(D_METHOD("get_version_info"), &Engine::get_version_info); + ClassDB::bind_method(D_METHOD("get_author_info"), &Engine::get_author_info); + ClassDB::bind_method(D_METHOD("get_copyright_info"), &Engine::get_copyright_info); + ClassDB::bind_method(D_METHOD("get_donor_info"), &Engine::get_donor_info); + ClassDB::bind_method(D_METHOD("get_license_info"), &Engine::get_license_info); + ClassDB::bind_method(D_METHOD("get_license_text"), &Engine::get_license_text); - ClassDB::bind_method(D_METHOD("is_in_physics_frame"), &_Engine::is_in_physics_frame); + ClassDB::bind_method(D_METHOD("is_in_physics_frame"), &Engine::is_in_physics_frame); - ClassDB::bind_method(D_METHOD("has_singleton", "name"), &_Engine::has_singleton); - ClassDB::bind_method(D_METHOD("get_singleton", "name"), &_Engine::get_singleton_object); + ClassDB::bind_method(D_METHOD("has_singleton", "name"), &Engine::has_singleton); + ClassDB::bind_method(D_METHOD("get_singleton", "name"), &Engine::get_singleton_object); - ClassDB::bind_method(D_METHOD("set_editor_hint", "enabled"), &_Engine::set_editor_hint); - ClassDB::bind_method(D_METHOD("is_editor_hint"), &_Engine::is_editor_hint); + ClassDB::bind_method(D_METHOD("set_editor_hint", "enabled"), &Engine::set_editor_hint); + ClassDB::bind_method(D_METHOD("is_editor_hint"), &Engine::is_editor_hint); - ClassDB::bind_method(D_METHOD("set_print_error_messages", "enabled"), &_Engine::set_print_error_messages); - ClassDB::bind_method(D_METHOD("is_printing_error_messages"), &_Engine::is_printing_error_messages); + ClassDB::bind_method(D_METHOD("set_print_error_messages", "enabled"), &Engine::set_print_error_messages); + ClassDB::bind_method(D_METHOD("is_printing_error_messages"), &Engine::is_printing_error_messages); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_hint"), "set_editor_hint", "is_editor_hint"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "print_error_messages"), "set_print_error_messages", "is_printing_error_messages"); @@ -2228,92 +2234,74 @@ void _Engine::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "physics_jitter_fix"), "set_physics_jitter_fix", "get_physics_jitter_fix"); } -_Engine *_Engine::singleton = nullptr; - -////// _EngineDebugger ////// - -void _EngineDebugger::_bind_methods() { - ClassDB::bind_method(D_METHOD("is_active"), &_EngineDebugger::is_active); - - ClassDB::bind_method(D_METHOD("register_profiler", "name", "toggle", "add", "tick"), &_EngineDebugger::register_profiler); - ClassDB::bind_method(D_METHOD("unregister_profiler", "name"), &_EngineDebugger::unregister_profiler); - ClassDB::bind_method(D_METHOD("is_profiling", "name"), &_EngineDebugger::is_profiling); - ClassDB::bind_method(D_METHOD("has_profiler", "name"), &_EngineDebugger::has_profiler); - - ClassDB::bind_method(D_METHOD("profiler_add_frame_data", "name", "data"), &_EngineDebugger::profiler_add_frame_data); - ClassDB::bind_method(D_METHOD("profiler_enable", "name", "enable", "arguments"), &_EngineDebugger::profiler_enable, DEFVAL(Array())); - - ClassDB::bind_method(D_METHOD("register_message_capture", "name", "callable"), &_EngineDebugger::register_message_capture); - ClassDB::bind_method(D_METHOD("unregister_message_capture", "name"), &_EngineDebugger::unregister_message_capture); - ClassDB::bind_method(D_METHOD("has_capture", "name"), &_EngineDebugger::has_capture); +Engine *Engine::singleton = nullptr; - ClassDB::bind_method(D_METHOD("send_message", "message", "data"), &_EngineDebugger::send_message); -} +////// EngineDebugger ////// -bool _EngineDebugger::is_active() { - return EngineDebugger::is_active(); +bool EngineDebugger::is_active() { + return ::EngineDebugger::is_active(); } -void _EngineDebugger::register_profiler(const StringName &p_name, const Callable &p_toggle, const Callable &p_add, const Callable &p_tick) { +void EngineDebugger::register_profiler(const StringName &p_name, const Callable &p_toggle, const Callable &p_add, const Callable &p_tick) { ERR_FAIL_COND_MSG(profilers.has(p_name) || has_profiler(p_name), "Profiler already registered: " + p_name); profilers.insert(p_name, ProfilerCallable(p_toggle, p_add, p_tick)); ProfilerCallable &p = profilers[p_name]; - EngineDebugger::Profiler profiler( + ::EngineDebugger::Profiler profiler( &p, - &_EngineDebugger::call_toggle, - &_EngineDebugger::call_add, - &_EngineDebugger::call_tick); - EngineDebugger::register_profiler(p_name, profiler); + &EngineDebugger::call_toggle, + &EngineDebugger::call_add, + &EngineDebugger::call_tick); + ::EngineDebugger::register_profiler(p_name, profiler); } -void _EngineDebugger::unregister_profiler(const StringName &p_name) { +void EngineDebugger::unregister_profiler(const StringName &p_name) { ERR_FAIL_COND_MSG(!profilers.has(p_name), "Profiler not registered: " + p_name); - EngineDebugger::unregister_profiler(p_name); + ::EngineDebugger::unregister_profiler(p_name); profilers.erase(p_name); } -bool _EngineDebugger::_EngineDebugger::is_profiling(const StringName &p_name) { - return EngineDebugger::is_profiling(p_name); +bool EngineDebugger::is_profiling(const StringName &p_name) { + return ::EngineDebugger::is_profiling(p_name); } -bool _EngineDebugger::has_profiler(const StringName &p_name) { - return EngineDebugger::has_profiler(p_name); +bool EngineDebugger::has_profiler(const StringName &p_name) { + return ::EngineDebugger::has_profiler(p_name); } -void _EngineDebugger::profiler_add_frame_data(const StringName &p_name, const Array &p_data) { - EngineDebugger::profiler_add_frame_data(p_name, p_data); +void EngineDebugger::profiler_add_frame_data(const StringName &p_name, const Array &p_data) { + ::EngineDebugger::profiler_add_frame_data(p_name, p_data); } -void _EngineDebugger::profiler_enable(const StringName &p_name, bool p_enabled, const Array &p_opts) { - if (EngineDebugger::get_singleton()) { - EngineDebugger::get_singleton()->profiler_enable(p_name, p_enabled, p_opts); +void EngineDebugger::profiler_enable(const StringName &p_name, bool p_enabled, const Array &p_opts) { + if (::EngineDebugger::get_singleton()) { + ::EngineDebugger::get_singleton()->profiler_enable(p_name, p_enabled, p_opts); } } -void _EngineDebugger::register_message_capture(const StringName &p_name, const Callable &p_callable) { +void EngineDebugger::register_message_capture(const StringName &p_name, const Callable &p_callable) { ERR_FAIL_COND_MSG(captures.has(p_name) || has_capture(p_name), "Capture already registered: " + p_name); captures.insert(p_name, p_callable); Callable &c = captures[p_name]; - EngineDebugger::Capture capture(&c, &_EngineDebugger::call_capture); - EngineDebugger::register_message_capture(p_name, capture); + ::EngineDebugger::Capture capture(&c, &EngineDebugger::call_capture); + ::EngineDebugger::register_message_capture(p_name, capture); } -void _EngineDebugger::unregister_message_capture(const StringName &p_name) { +void EngineDebugger::unregister_message_capture(const StringName &p_name) { ERR_FAIL_COND_MSG(!captures.has(p_name), "Capture not registered: " + p_name); - EngineDebugger::unregister_message_capture(p_name); + ::EngineDebugger::unregister_message_capture(p_name); captures.erase(p_name); } -bool _EngineDebugger::has_capture(const StringName &p_name) { - return EngineDebugger::has_capture(p_name); +bool EngineDebugger::has_capture(const StringName &p_name) { + return ::EngineDebugger::has_capture(p_name); } -void _EngineDebugger::send_message(const String &p_msg, const Array &p_data) { - ERR_FAIL_COND_MSG(!EngineDebugger::is_active(), "Can't send message. No active debugger"); - EngineDebugger::get_singleton()->send_message(p_msg, p_data); +void EngineDebugger::send_message(const String &p_msg, const Array &p_data) { + ERR_FAIL_COND_MSG(!::EngineDebugger::is_active(), "Can't send message. No active debugger"); + ::EngineDebugger::get_singleton()->send_message(p_msg, p_data); } -void _EngineDebugger::call_toggle(void *p_user, bool p_enable, const Array &p_opts) { +void EngineDebugger::call_toggle(void *p_user, bool p_enable, const Array &p_opts) { Callable &toggle = ((ProfilerCallable *)p_user)->callable_toggle; if (toggle.is_null()) { return; @@ -2326,7 +2314,7 @@ void _EngineDebugger::call_toggle(void *p_user, bool p_enable, const Array &p_op ERR_FAIL_COND_MSG(err.error != Callable::CallError::CALL_OK, "Error calling 'toggle' to callable: " + Variant::get_callable_error_text(toggle, args, 2, err)); } -void _EngineDebugger::call_add(void *p_user, const Array &p_data) { +void EngineDebugger::call_add(void *p_user, const Array &p_data) { Callable &add = ((ProfilerCallable *)p_user)->callable_add; if (add.is_null()) { return; @@ -2339,7 +2327,7 @@ void _EngineDebugger::call_add(void *p_user, const Array &p_data) { ERR_FAIL_COND_MSG(err.error != Callable::CallError::CALL_OK, "Error calling 'add' to callable: " + Variant::get_callable_error_text(add, args, 1, err)); } -void _EngineDebugger::call_tick(void *p_user, double p_frame_time, double p_idle_time, double p_physics_time, double p_physics_frame_time) { +void EngineDebugger::call_tick(void *p_user, double p_frame_time, double p_idle_time, double p_physics_time, double p_physics_frame_time) { Callable &tick = ((ProfilerCallable *)p_user)->callable_tick; if (tick.is_null()) { return; @@ -2352,7 +2340,7 @@ void _EngineDebugger::call_tick(void *p_user, double p_frame_time, double p_idle ERR_FAIL_COND_MSG(err.error != Callable::CallError::CALL_OK, "Error calling 'tick' to callable: " + Variant::get_callable_error_text(tick, args, 4, err)); } -Error _EngineDebugger::call_capture(void *p_user, const String &p_cmd, const Array &p_data, bool &r_captured) { +Error EngineDebugger::call_capture(void *p_user, const String &p_cmd, const Array &p_data, bool &r_captured) { Callable &capture = *(Callable *)p_user; if (capture.is_null()) { return FAILED; @@ -2368,15 +2356,35 @@ Error _EngineDebugger::call_capture(void *p_user, const String &p_cmd, const Arr return OK; } -_EngineDebugger::~_EngineDebugger() { +EngineDebugger::~EngineDebugger() { for (Map<StringName, Callable>::Element *E = captures.front(); E; E = E->next()) { - EngineDebugger::unregister_message_capture(E->key()); + ::EngineDebugger::unregister_message_capture(E->key()); } captures.clear(); for (Map<StringName, ProfilerCallable>::Element *E = profilers.front(); E; E = E->next()) { - EngineDebugger::unregister_profiler(E->key()); + ::EngineDebugger::unregister_profiler(E->key()); } profilers.clear(); } -_EngineDebugger *_EngineDebugger::singleton = nullptr; +EngineDebugger *EngineDebugger::singleton = nullptr; + +void EngineDebugger::_bind_methods() { + ClassDB::bind_method(D_METHOD("is_active"), &EngineDebugger::is_active); + + ClassDB::bind_method(D_METHOD("register_profiler", "name", "toggle", "add", "tick"), &EngineDebugger::register_profiler); + ClassDB::bind_method(D_METHOD("unregister_profiler", "name"), &EngineDebugger::unregister_profiler); + ClassDB::bind_method(D_METHOD("is_profiling", "name"), &EngineDebugger::is_profiling); + ClassDB::bind_method(D_METHOD("has_profiler", "name"), &EngineDebugger::has_profiler); + + ClassDB::bind_method(D_METHOD("profiler_add_frame_data", "name", "data"), &EngineDebugger::profiler_add_frame_data); + ClassDB::bind_method(D_METHOD("profiler_enable", "name", "enable", "arguments"), &EngineDebugger::profiler_enable, DEFVAL(Array())); + + ClassDB::bind_method(D_METHOD("register_message_capture", "name", "callable"), &EngineDebugger::register_message_capture); + ClassDB::bind_method(D_METHOD("unregister_message_capture", "name"), &EngineDebugger::unregister_message_capture); + ClassDB::bind_method(D_METHOD("has_capture", "name"), &EngineDebugger::has_capture); + + ClassDB::bind_method(D_METHOD("send_message", "message", "data"), &EngineDebugger::send_message); +} + +} // namespace core_bind diff --git a/core/core_bind.h b/core/core_bind.h index 94e8ab2a34..1dbe49f418 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -42,12 +42,16 @@ #include "core/os/thread.h" #include "core/templates/safe_refcount.h" -class _ResourceLoader : public Object { - GDCLASS(_ResourceLoader, Object); +class MainLoop; + +namespace core_bind { + +class ResourceLoader : public Object { + GDCLASS(ResourceLoader, Object); protected: static void _bind_methods(); - static _ResourceLoader *singleton; + static ResourceLoader *singleton; public: enum ThreadLoadStatus { @@ -63,7 +67,7 @@ public: CACHE_MODE_REPLACE, // Resource and subresource use path cache, but replace existing loaded resources when available with information from disk. }; - static _ResourceLoader *get_singleton() { return singleton; } + static ResourceLoader *get_singleton() { return singleton; } Error load_threaded_request(const String &p_path, const String &p_type_hint = "", bool p_use_sub_threads = false); ThreadLoadStatus load_threaded_get_status(const String &p_path, Array r_progress = Array()); @@ -77,18 +81,15 @@ public: bool exists(const String &p_path, const String &p_type_hint = ""); ResourceUID::ID get_resource_uid(const String &p_path); - _ResourceLoader() { singleton = this; } + ResourceLoader() { singleton = this; } }; -VARIANT_ENUM_CAST(_ResourceLoader::ThreadLoadStatus); -VARIANT_ENUM_CAST(_ResourceLoader::CacheMode); - -class _ResourceSaver : public Object { - GDCLASS(_ResourceSaver, Object); +class ResourceSaver : public Object { + GDCLASS(ResourceSaver, Object); protected: static void _bind_methods(); - static _ResourceSaver *singleton; + static ResourceSaver *singleton; public: enum SaverFlags { @@ -101,24 +102,20 @@ public: FLAG_REPLACE_SUBRESOURCE_PATHS = 64, }; - static _ResourceSaver *get_singleton() { return singleton; } + static ResourceSaver *get_singleton() { return singleton; } Error save(const String &p_path, const RES &p_resource, SaverFlags p_flags); Vector<String> get_recognized_extensions(const RES &p_resource); - _ResourceSaver() { singleton = this; } + ResourceSaver() { singleton = this; } }; -VARIANT_ENUM_CAST(_ResourceSaver::SaverFlags); - -class MainLoop; - -class _OS : public Object { - GDCLASS(_OS, Object); +class OS : public Object { + GDCLASS(OS, Object); protected: static void _bind_methods(); - static _OS *singleton; + static OS *singleton; public: enum VideoDriver { @@ -245,26 +242,21 @@ public: bool request_permissions(); Vector<String> get_granted_permissions() const; - static _OS *get_singleton() { return singleton; } + static OS *get_singleton() { return singleton; } - _OS() { singleton = this; } + OS() { singleton = this; } }; -VARIANT_ENUM_CAST(_OS::VideoDriver); -VARIANT_ENUM_CAST(_OS::Weekday); -VARIANT_ENUM_CAST(_OS::Month); -VARIANT_ENUM_CAST(_OS::SystemDir); +class Geometry2D : public Object { + GDCLASS(Geometry2D, Object); -class _Geometry2D : public Object { - GDCLASS(_Geometry2D, Object); - - static _Geometry2D *singleton; + static Geometry2D *singleton; protected: static void _bind_methods(); public: - static _Geometry2D *get_singleton(); + static Geometry2D *get_singleton(); Variant segment_intersects_segment(const Vector2 &p_from_a, const Vector2 &p_to_a, const Vector2 &p_from_b, const Vector2 &p_to_b); Variant line_intersects_line(const Vector2 &p_from_a, const Vector2 &p_dir_a, const Vector2 &p_from_b, const Vector2 &p_dir_b); Vector<Vector2> get_closest_points_between_segments(const Vector2 &p1, const Vector2 &q1, const Vector2 &p2, const Vector2 &q2); @@ -315,23 +307,19 @@ public: Dictionary make_atlas(const Vector<Size2> &p_rects); - _Geometry2D() { singleton = this; } + Geometry2D() { singleton = this; } }; -VARIANT_ENUM_CAST(_Geometry2D::PolyBooleanOperation); -VARIANT_ENUM_CAST(_Geometry2D::PolyJoinType); -VARIANT_ENUM_CAST(_Geometry2D::PolyEndType); - -class _Geometry3D : public Object { - GDCLASS(_Geometry3D, Object); +class Geometry3D : public Object { + GDCLASS(Geometry3D, Object); - static _Geometry3D *singleton; + static Geometry3D *singleton; protected: static void _bind_methods(); public: - static _Geometry3D *get_singleton(); + static Geometry3D *get_singleton(); Vector<Plane> build_box_planes(const Vector3 &p_extents); Vector<Plane> build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis = Vector3::AXIS_Z); Vector<Plane> build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis = Vector3::AXIS_Z); @@ -347,11 +335,11 @@ public: Vector<Vector3> clip_polygon(const Vector<Vector3> &p_points, const Plane &p_plane); - _Geometry3D() { singleton = this; } + Geometry3D() { singleton = this; } }; -class _File : public RefCounted { - GDCLASS(_File, RefCounted); +class File : public RefCounted { + GDCLASS(File, RefCounted); FileAccess *f = nullptr; bool big_endian = false; @@ -445,15 +433,12 @@ public: uint64_t get_modified_time(const String &p_file) const; - _File() {} - virtual ~_File(); + File() {} + virtual ~File(); }; -VARIANT_ENUM_CAST(_File::ModeFlags); -VARIANT_ENUM_CAST(_File::CompressionMode); - -class _Directory : public RefCounted { - GDCLASS(_Directory, RefCounted); +class Directory : public RefCounted { + GDCLASS(Directory, RefCounted); DirAccess *d; bool dir_open = false; @@ -490,24 +475,24 @@ public: Error rename(String p_from, String p_to); Error remove(String p_name); - _Directory(); - virtual ~_Directory(); + Directory(); + virtual ~Directory(); private: bool _list_skip_navigational = false; bool _list_skip_hidden = false; }; -class _Marshalls : public Object { - GDCLASS(_Marshalls, Object); +class Marshalls : public Object { + GDCLASS(Marshalls, Object); - static _Marshalls *singleton; + static Marshalls *singleton; protected: static void _bind_methods(); public: - static _Marshalls *get_singleton(); + static Marshalls *get_singleton(); String variant_to_base64(const Variant &p_var, bool p_full_objects = false); Variant base64_to_variant(const String &p_str, bool p_allow_objects = false); @@ -518,13 +503,13 @@ public: String utf8_to_base64(const String &p_str); String base64_to_utf8(const String &p_str); - _Marshalls() { singleton = this; } - ~_Marshalls() { singleton = nullptr; } + Marshalls() { singleton = this; } + ~Marshalls() { singleton = nullptr; } }; -class _Mutex : public RefCounted { - GDCLASS(_Mutex, RefCounted); - Mutex mutex; +class Mutex : public RefCounted { + GDCLASS(Mutex, RefCounted); + ::Mutex mutex; static void _bind_methods(); @@ -534,9 +519,9 @@ public: void unlock(); }; -class _Semaphore : public RefCounted { - GDCLASS(_Semaphore, RefCounted); - Semaphore semaphore; +class Semaphore : public RefCounted { + GDCLASS(Semaphore, RefCounted); + ::Semaphore semaphore; static void _bind_methods(); @@ -546,8 +531,8 @@ public: void post(); }; -class _Thread : public RefCounted { - GDCLASS(_Thread, RefCounted); +class Thread : public RefCounted { + GDCLASS(Thread, RefCounted); protected: Variant ret; @@ -555,7 +540,7 @@ protected: SafeFlag active; Object *target_instance = nullptr; StringName target_method; - Thread thread; + ::Thread thread; static void _bind_methods(); static void _start_func(void *ud); @@ -573,10 +558,10 @@ public: Variant wait_to_finish(); }; -VARIANT_ENUM_CAST(_Thread::Priority); +namespace special { -class _ClassDB : public Object { - GDCLASS(_ClassDB, Object); +class ClassDB : public Object { + GDCLASS(ClassDB, Object); protected: static void _bind_methods(); @@ -609,19 +594,21 @@ public: bool is_class_enabled(StringName p_class) const; - _ClassDB() {} - ~_ClassDB() {} + ClassDB() {} + ~ClassDB() {} }; -class _Engine : public Object { - GDCLASS(_Engine, Object); +} // namespace special + +class Engine : public Object { + GDCLASS(Engine, Object); protected: static void _bind_methods(); - static _Engine *singleton; + static Engine *singleton; public: - static _Engine *get_singleton() { return singleton; } + static Engine *get_singleton() { return singleton; } void set_physics_ticks_per_second(int p_ips); int get_physics_ticks_per_second() const; @@ -661,14 +648,14 @@ public: void set_print_error_messages(bool p_enabled); bool is_printing_error_messages() const; - _Engine() { singleton = this; } + Engine() { singleton = this; } }; -class _EngineDebugger : public Object { - GDCLASS(_EngineDebugger, Object); +class EngineDebugger : public Object { + GDCLASS(EngineDebugger, Object); class ProfilerCallable { - friend class _EngineDebugger; + friend class EngineDebugger; Callable callable_toggle; Callable callable_add; @@ -689,10 +676,10 @@ class _EngineDebugger : public Object { protected: static void _bind_methods(); - static _EngineDebugger *singleton; + static EngineDebugger *singleton; public: - static _EngineDebugger *get_singleton() { return singleton; } + static EngineDebugger *get_singleton() { return singleton; } bool is_active(); @@ -714,8 +701,29 @@ public: static void call_tick(void *p_user, double p_frame_time, double p_idle_time, double p_physics_time, double p_physics_frame_time); static Error call_capture(void *p_user, const String &p_cmd, const Array &p_data, bool &r_captured); - _EngineDebugger() { singleton = this; } - ~_EngineDebugger(); + EngineDebugger() { singleton = this; } + ~EngineDebugger(); }; +} // namespace core_bind + +VARIANT_ENUM_CAST(core_bind::ResourceLoader::ThreadLoadStatus); +VARIANT_ENUM_CAST(core_bind::ResourceLoader::CacheMode); + +VARIANT_ENUM_CAST(core_bind::ResourceSaver::SaverFlags); + +VARIANT_ENUM_CAST(core_bind::OS::VideoDriver); +VARIANT_ENUM_CAST(core_bind::OS::Weekday); +VARIANT_ENUM_CAST(core_bind::OS::Month); +VARIANT_ENUM_CAST(core_bind::OS::SystemDir); + +VARIANT_ENUM_CAST(core_bind::Geometry2D::PolyBooleanOperation); +VARIANT_ENUM_CAST(core_bind::Geometry2D::PolyJoinType); +VARIANT_ENUM_CAST(core_bind::Geometry2D::PolyEndType); + +VARIANT_ENUM_CAST(core_bind::File::ModeFlags); +VARIANT_ENUM_CAST(core_bind::File::CompressionMode); + +VARIANT_ENUM_CAST(core_bind::Thread::Priority); + #endif // CORE_BIND_H diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index c58fe7bc24..75145e1b65 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -1068,6 +1068,20 @@ void ClassDB::set_property_default_value(const StringName &p_class, const String default_values[p_class][p_name] = p_default; } +void ClassDB::add_linked_property(const StringName &p_class, const String &p_property, const String &p_linked_property) { +#ifdef TOOLS_ENABLED + OBJTYPE_WLOCK; + ClassInfo *type = classes.getptr(p_class); + ERR_FAIL_COND(!type); + + ERR_FAIL_COND(!type->property_map.has(p_property)); + ERR_FAIL_COND(!type->property_map.has(p_linked_property)); + + PropertyInfo &pinfo = type->property_map[p_property]; + pinfo.linked_properties.push_back(p_linked_property); +#endif +} + void ClassDB::get_property_list(const StringName &p_class, List<PropertyInfo> *p_list, bool p_no_inheritance, const Object *p_validator) { OBJTYPE_RLOCK; diff --git a/core/object/class_db.h b/core/object/class_db.h index bfc9d6f283..8add0285f7 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -330,7 +330,7 @@ public: if (type->method_map.has(p_name)) { memdelete(bind); - // overloading not supported + // Overloading not supported ERR_FAIL_V_MSG(nullptr, "Method already bound: " + instance_type + "::" + p_name + "."); } type->method_map[p_name] = bind; @@ -354,6 +354,7 @@ public: static void add_property_subgroup(const StringName &p_class, const String &p_name, const String &p_prefix = ""); static void add_property(const StringName &p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index = -1); static void set_property_default_value(const StringName &p_class, const StringName &p_name, const Variant &p_default); + static void add_linked_property(const StringName &p_class, const String &p_property, const String &p_linked_property); static void get_property_list(const StringName &p_class, List<PropertyInfo> *p_list, bool p_no_inheritance = false, const Object *p_validator = nullptr); static bool get_property_info(const StringName &p_class, const StringName &p_property, PropertyInfo *r_info, bool p_no_inheritance = false, const Object *p_validator = nullptr); static bool set_property(Object *p_object, const StringName &p_property, const Variant &p_value, bool *r_valid = nullptr); @@ -409,25 +410,25 @@ public: #ifdef DEBUG_METHODS_ENABLED #define BIND_CONSTANT(m_constant) \ - ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant); + ::ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant); #define BIND_ENUM_CONSTANT(m_constant) \ - ClassDB::bind_integer_constant(get_class_static(), __constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant); + ::ClassDB::bind_integer_constant(get_class_static(), __constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant); #else #define BIND_CONSTANT(m_constant) \ - ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant); + ::ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant); #define BIND_ENUM_CONSTANT(m_constant) \ - ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant); + ::ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant); #endif #ifdef TOOLS_ENABLED #define BIND_VMETHOD(m_method) \ - ClassDB::add_virtual_method(get_class_static(), m_method); + ::ClassDB::add_virtual_method(get_class_static(), m_method); #else @@ -437,11 +438,11 @@ public: #define GDREGISTER_CLASS(m_class) \ if (!GD_IS_DEFINED(ClassDB_Disable_##m_class)) { \ - ClassDB::register_class<m_class>(); \ + ::ClassDB::register_class<m_class>(); \ } -#define GDREGISTER_VIRTUAL_CLASS(m_class) \ - if (!GD_IS_DEFINED(ClassDB_Disable_##m_class)) { \ - ClassDB::register_virtual_class<m_class>(); \ +#define GDREGISTER_VIRTUAL_CLASS(m_class) \ + if (!GD_IS_DEFINED(ClassDB_Disable_##m_class)) { \ + ::ClassDB::register_virtual_class<m_class>(); \ } #include "core/disabled_classes.gen.h" diff --git a/core/object/object.h b/core/object/object.h index 6523105820..94531f1cd0 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -137,21 +137,26 @@ enum PropertyUsageFlags { PROPERTY_USAGE_NOEDITOR = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_NETWORK, }; -#define ADD_SIGNAL(m_signal) ClassDB::add_signal(get_class_static(), m_signal) -#define ADD_PROPERTY(m_property, m_setter, m_getter) ClassDB::add_property(get_class_static(), m_property, _scs_create(m_setter), _scs_create(m_getter)) -#define ADD_PROPERTYI(m_property, m_setter, m_getter, m_index) ClassDB::add_property(get_class_static(), m_property, _scs_create(m_setter), _scs_create(m_getter), m_index) -#define ADD_PROPERTY_DEFAULT(m_property, m_default) ClassDB::set_property_default_value(get_class_static(), m_property, m_default) -#define ADD_GROUP(m_name, m_prefix) ClassDB::add_property_group(get_class_static(), m_name, m_prefix) -#define ADD_SUBGROUP(m_name, m_prefix) ClassDB::add_property_subgroup(get_class_static(), m_name, m_prefix) +#define ADD_SIGNAL(m_signal) ::ClassDB::add_signal(get_class_static(), m_signal) +#define ADD_PROPERTY(m_property, m_setter, m_getter) ::ClassDB::add_property(get_class_static(), m_property, _scs_create(m_setter), _scs_create(m_getter)) +#define ADD_PROPERTYI(m_property, m_setter, m_getter, m_index) ::ClassDB::add_property(get_class_static(), m_property, _scs_create(m_setter), _scs_create(m_getter), m_index) +#define ADD_PROPERTY_DEFAULT(m_property, m_default) ::ClassDB::set_property_default_value(get_class_static(), m_property, m_default) +#define ADD_GROUP(m_name, m_prefix) ::ClassDB::add_property_group(get_class_static(), m_name, m_prefix) +#define ADD_SUBGROUP(m_name, m_prefix) ::ClassDB::add_property_subgroup(get_class_static(), m_name, m_prefix) +#define ADD_LINKED_PROPERTY(m_property, m_linked_property) ::ClassDB::add_linked_property(get_class_static(), m_property, m_linked_property) struct PropertyInfo { Variant::Type type = Variant::NIL; String name; - StringName class_name; //for classes + StringName class_name; // For classes PropertyHint hint = PROPERTY_HINT_NONE; String hint_string; uint32_t usage = PROPERTY_USAGE_DEFAULT; +#ifdef TOOLS_ENABLED + Vector<String> linked_properties; +#endif + _FORCE_INLINE_ PropertyInfo added_usage(uint32_t p_fl) const { PropertyInfo pi = *this; pi.usage |= p_fl; @@ -277,7 +282,7 @@ struct ObjectNativeExtension { }; #define GDVIRTUAL_CALL(m_name, ...) _gdvirtual_##m_name##_call(__VA_ARGS__) -#define GDVIRTUAL_BIND(m_name) ClassDB::add_virtual_method(get_class_static(), _gdvirtual_##m_name##_get_method_info()); +#define GDVIRTUAL_BIND(m_name) ::ClassDB::add_virtual_method(get_class_static(), _gdvirtual_##m_name##_get_method_info()); /* the following is an incomprehensible blob of hacks and workarounds to compensate for many of the fallencies in C++. As a plus, this macro pretty much alone defines the object model. @@ -299,7 +304,7 @@ private: private: \ void operator=(const m_class &p_rval) {} \ mutable StringName _class_name; \ - friend class ClassDB; \ + friend class ::ClassDB; \ \ public: \ virtual String get_class() const override { \ @@ -372,7 +377,7 @@ public: return; \ } \ m_inherits::initialize_class(); \ - ClassDB::_add_class<m_class>(); \ + ::ClassDB::_add_class<m_class>(); \ if (m_class::_get_bind_methods() != m_inherits::_get_bind_methods()) { \ _bind_methods(); \ } \ @@ -415,13 +420,13 @@ protected: } \ p_list->push_back(PropertyInfo(Variant::NIL, get_class_static(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY)); \ if (!_is_gpl_reversed()) { \ - ClassDB::get_property_list(#m_class, p_list, true, this); \ + ::ClassDB::get_property_list(#m_class, p_list, true, this); \ } \ if (m_class::_get_get_property_list() != m_inherits::_get_get_property_list()) { \ _get_property_list(p_list); \ } \ if (_is_gpl_reversed()) { \ - ClassDB::get_property_list(#m_class, p_list, true, this); \ + ::ClassDB::get_property_list(#m_class, p_list, true, this); \ } \ if (p_reversed) { \ m_inherits::_get_property_listv(p_list, p_reversed); \ diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index 4fabd1551e..e2a097f883 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -85,18 +85,18 @@ static Ref<ResourceFormatSaverCrypto> resource_format_saver_crypto; static Ref<ResourceFormatLoaderCrypto> resource_format_loader_crypto; static Ref<NativeExtensionResourceLoader> resource_loader_native_extension; -static _ResourceLoader *_resource_loader = nullptr; -static _ResourceSaver *_resource_saver = nullptr; -static _OS *_os = nullptr; -static _Engine *_engine = nullptr; -static _ClassDB *_classdb = nullptr; -static _Marshalls *_marshalls = nullptr; -static _EngineDebugger *_engine_debugger = nullptr; +static core_bind::ResourceLoader *_resource_loader = nullptr; +static core_bind::ResourceSaver *_resource_saver = nullptr; +static core_bind::OS *_os = nullptr; +static core_bind::Engine *_engine = nullptr; +static core_bind::special::ClassDB *_classdb = nullptr; +static core_bind::Marshalls *_marshalls = nullptr; +static core_bind::EngineDebugger *_engine_debugger = nullptr; static IP *ip = nullptr; -static _Geometry2D *_geometry_2d = nullptr; -static _Geometry3D *_geometry_3d = nullptr; +static core_bind::Geometry2D *_geometry_2d = nullptr; +static core_bind::Geometry3D *_geometry_3d = nullptr; extern Mutex _global_mutex; @@ -205,11 +205,11 @@ void register_core_types() { GDREGISTER_CLASS(ResourceFormatLoader); GDREGISTER_CLASS(ResourceFormatSaver); - GDREGISTER_CLASS(_File); - GDREGISTER_CLASS(_Directory); - GDREGISTER_CLASS(_Thread); - GDREGISTER_CLASS(_Mutex); - GDREGISTER_CLASS(_Semaphore); + GDREGISTER_CLASS(core_bind::File); + GDREGISTER_CLASS(core_bind::Directory); + GDREGISTER_CLASS(core_bind::Thread); + GDREGISTER_CLASS(core_bind::Mutex); + GDREGISTER_CLASS(core_bind::Semaphore); GDREGISTER_CLASS(XMLParser); GDREGISTER_CLASS(JSON); @@ -242,16 +242,16 @@ void register_core_types() { ip = IP::create(); - _geometry_2d = memnew(_Geometry2D); - _geometry_3d = memnew(_Geometry3D); + _geometry_2d = memnew(core_bind::Geometry2D); + _geometry_3d = memnew(core_bind::Geometry3D); - _resource_loader = memnew(_ResourceLoader); - _resource_saver = memnew(_ResourceSaver); - _os = memnew(_OS); - _engine = memnew(_Engine); - _classdb = memnew(_ClassDB); - _marshalls = memnew(_Marshalls); - _engine_debugger = memnew(_EngineDebugger); + _resource_loader = memnew(core_bind::ResourceLoader); + _resource_saver = memnew(core_bind::ResourceSaver); + _os = memnew(core_bind::OS); + _engine = memnew(core_bind::Engine); + _classdb = memnew(core_bind::special::ClassDB); + _marshalls = memnew(core_bind::Marshalls); + _engine_debugger = memnew(core_bind::EngineDebugger); } void register_core_settings() { @@ -268,35 +268,35 @@ void register_core_settings() { void register_core_singletons() { GDREGISTER_CLASS(ProjectSettings); GDREGISTER_VIRTUAL_CLASS(IP); - GDREGISTER_CLASS(_Geometry2D); - GDREGISTER_CLASS(_Geometry3D); - GDREGISTER_CLASS(_ResourceLoader); - GDREGISTER_CLASS(_ResourceSaver); - GDREGISTER_CLASS(_OS); - GDREGISTER_CLASS(_Engine); - GDREGISTER_CLASS(_ClassDB); - GDREGISTER_CLASS(_Marshalls); + GDREGISTER_CLASS(core_bind::Geometry2D); + GDREGISTER_CLASS(core_bind::Geometry3D); + GDREGISTER_CLASS(core_bind::ResourceLoader); + GDREGISTER_CLASS(core_bind::ResourceSaver); + GDREGISTER_CLASS(core_bind::OS); + GDREGISTER_CLASS(core_bind::Engine); + GDREGISTER_CLASS(core_bind::special::ClassDB); + GDREGISTER_CLASS(core_bind::Marshalls); GDREGISTER_CLASS(TranslationServer); GDREGISTER_VIRTUAL_CLASS(Input); GDREGISTER_CLASS(InputMap); GDREGISTER_CLASS(Expression); - GDREGISTER_CLASS(_EngineDebugger); + GDREGISTER_CLASS(core_bind::EngineDebugger); GDREGISTER_CLASS(Time); Engine::get_singleton()->add_singleton(Engine::Singleton("ProjectSettings", ProjectSettings::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("IP", IP::get_singleton(), "IP")); - Engine::get_singleton()->add_singleton(Engine::Singleton("Geometry2D", _Geometry2D::get_singleton())); - Engine::get_singleton()->add_singleton(Engine::Singleton("Geometry3D", _Geometry3D::get_singleton())); - Engine::get_singleton()->add_singleton(Engine::Singleton("ResourceLoader", _ResourceLoader::get_singleton())); - Engine::get_singleton()->add_singleton(Engine::Singleton("ResourceSaver", _ResourceSaver::get_singleton())); - Engine::get_singleton()->add_singleton(Engine::Singleton("OS", _OS::get_singleton())); - Engine::get_singleton()->add_singleton(Engine::Singleton("Engine", _Engine::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("Geometry2D", core_bind::Geometry2D::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("Geometry3D", core_bind::Geometry3D::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("ResourceLoader", core_bind::ResourceLoader::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("ResourceSaver", core_bind::ResourceSaver::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("OS", core_bind::OS::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("Engine", core_bind::Engine::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("ClassDB", _classdb)); - Engine::get_singleton()->add_singleton(Engine::Singleton("Marshalls", _Marshalls::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("Marshalls", core_bind::Marshalls::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("TranslationServer", TranslationServer::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("Input", Input::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("InputMap", InputMap::get_singleton())); - Engine::get_singleton()->add_singleton(Engine::Singleton("EngineDebugger", _EngineDebugger::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("EngineDebugger", core_bind::EngineDebugger::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("Time", Time::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("NativeExtensionManager", NativeExtensionManager::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("ResourceUID", ResourceUID::get_singleton())); diff --git a/core/variant/type_info.h b/core/variant/type_info.h index 76cb065d10..b70d29bbac 100644 --- a/core/variant/type_info.h +++ b/core/variant/type_info.h @@ -241,14 +241,27 @@ struct GetTypeInfo<const T *, typename EnableIf<TypeInherits<Object, T>::value>: } }; -#define TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_impl) \ - template <> \ - struct GetTypeInfo<m_impl> { \ - static const Variant::Type VARIANT_TYPE = Variant::INT; \ - static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \ - static inline PropertyInfo get_class_info() { \ - return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_ENUM, String(#m_enum).replace("::", ".")); \ - } \ +namespace godot { +namespace details { +inline String enum_qualified_name_to_class_info_name(const String &p_qualified_name) { + Vector<String> parts = p_qualified_name.split("::", false); + if (parts.size() <= 2) + return String(".").join(parts); + // Contains namespace. We only want the class and enum names. + return parts[parts.size() - 2] + "." + parts[parts.size() - 1]; +} +} // namespace details +} // namespace godot + +#define TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_impl) \ + template <> \ + struct GetTypeInfo<m_impl> { \ + static const Variant::Type VARIANT_TYPE = Variant::INT; \ + static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \ + static inline PropertyInfo get_class_info() { \ + return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_ENUM, \ + godot::details::enum_qualified_name_to_class_info_name(String(#m_enum))); \ + } \ }; #define MAKE_ENUM_TYPE_INFO(m_enum) \ diff --git a/doc/classes/DirectionalLight3D.xml b/doc/classes/DirectionalLight3D.xml index 0060368207..e3badea0f4 100644 --- a/doc/classes/DirectionalLight3D.xml +++ b/doc/classes/DirectionalLight3D.xml @@ -36,7 +36,7 @@ <member name="directional_shadow_split_3" type="float" setter="set_param" getter="get_param" default="0.5"> The distance from shadow split 2 to split 3. Relative to [member directional_shadow_max_distance]. Only used when [member directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]. </member> - <member name="shadow_normal_bias" type="float" setter="set_param" getter="get_param" override="true" default="1.0" /> + <member name="shadow_bias" type="float" setter="set_param" getter="get_param" override="true" default="0.1" /> <member name="use_in_sky_only" type="bool" setter="set_sky_only" getter="is_sky_only" default="false"> If [code]true[/code], this [DirectionalLight3D] will not be used for anything except sky shaders. Use this for lights that impact your sky shader that you may want to hide from affecting the rest of the scene. For example, you may want to enable this when the sun in your sky shader falls below the horizon. </member> diff --git a/doc/classes/Light3D.xml b/doc/classes/Light3D.xml index 380e9314d4..cd2f4eca18 100644 --- a/doc/classes/Light3D.xml +++ b/doc/classes/Light3D.xml @@ -61,7 +61,7 @@ <member name="light_specular" type="float" setter="set_param" getter="get_param" default="0.5"> The intensity of the specular blob in objects affected by the light. At [code]0[/code], the light becomes a pure diffuse light. When not baking emission, this can be used to avoid unrealistic reflections when placing lights above an emissive surface. </member> - <member name="shadow_bias" type="float" setter="set_param" getter="get_param" default="0.1"> + <member name="shadow_bias" type="float" setter="set_param" getter="get_param" default="0.2"> Used to adjust shadow appearance. Too small a value results in self-shadowing ("shadow acne"), while too large a value causes shadows to separate from casters ("peter-panning"). Adjust as needed. </member> <member name="shadow_blur" type="float" setter="set_param" getter="get_param" default="1.0"> @@ -75,7 +75,7 @@ </member> <member name="shadow_fog_fade" type="float" setter="set_param" getter="get_param" default="0.1"> </member> - <member name="shadow_normal_bias" type="float" setter="set_param" getter="get_param" default="2.0"> + <member name="shadow_normal_bias" type="float" setter="set_param" getter="get_param" default="1.0"> Offsets the lookup into the shadow map by the object's normal. This can be used to reduce self-shadowing artifacts without using [member shadow_bias]. In practice, this value should be tweaked along with [member shadow_bias] to reduce artifacts as much as possible. </member> <member name="shadow_reverse_cull_face" type="bool" setter="set_shadow_reverse_cull_face" getter="get_shadow_reverse_cull_face" default="false"> diff --git a/doc/classes/TextFile.xml b/doc/classes/TextFile.xml deleted file mode 100644 index 1c2c2ff25c..0000000000 --- a/doc/classes/TextFile.xml +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="TextFile" inherits="Resource" version="4.0"> - <brief_description> - </brief_description> - <description> - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/float.xml b/doc/classes/float.xml index 60878eb0bd..4bf04fe25f 100644 --- a/doc/classes/float.xml +++ b/doc/classes/float.xml @@ -4,9 +4,13 @@ Float built-in type. </brief_description> <description> - Float built-in type. + The [float] built-in type is a 64-bit double-precision floating-point number, equivalent to [code]double[/code] in C++. This type has 14 reliable decimal digits of precision. The [float] type can be stored in [Variant], which is the generic type used by the engine. The maximum value of [float] is approximately [code]1.79769e308[/code], and the minimum is approximately [code]-1.79769e308[/code]. + Many methods and properties in the engine use 32-bit single-precision floating-point numbers instead, equivalent to [code]float[/code] in C++, which have 6 reliable decimal digits of precision. For data structures such as [Vector2] and [Vector3], Godot uses 32-bit floating-point numbers by default, but it can be changed to use 64-bit doubles if Godot is compiled with the [code]float=64[/code] option. + Math done using the [float] type is not guaranteed to be exact or deterministic, and will often result in small errors. You should usually use the [method @GlobalScope.is_equal_approx] and [method @GlobalScope.is_zero_approx] methods instead of [code]==[/code] to compare [float] values for equality. </description> <tutorials> + <link title="Wikipedia: Double-precision floating-point format">https://en.wikipedia.org/wiki/Double-precision_floating-point_format</link> + <link title="Wikipedia: Single-precision floating-point format">https://en.wikipedia.org/wiki/Single-precision_floating-point_format</link> </tutorials> <methods> <method name="float" qualifiers="constructor"> @@ -231,11 +235,13 @@ <method name="operator unary+" qualifiers="operator"> <return type="float" /> <description> + Returns the same value as if the [code]+[/code] was not there. Unary [code]+[/code] does nothing, but sometimes it can make your code more readable. </description> </method> <method name="operator unary-" qualifiers="operator"> <return type="float" /> <description> + Returns the negative value of the [float]. If positive, turns the number negative. If negative, turns the number positive. With floats, the number zero can be either positive or negative. </description> </method> </methods> diff --git a/doc/classes/int.xml b/doc/classes/int.xml index 84a01aa0d0..32b5fe1012 100644 --- a/doc/classes/int.xml +++ b/doc/classes/int.xml @@ -327,11 +327,13 @@ <method name="operator unary+" qualifiers="operator"> <return type="int" /> <description> + Returns the same value as if the [code]+[/code] was not there. Unary [code]+[/code] does nothing, but sometimes it can make your code more readable. </description> </method> <method name="operator unary-" qualifiers="operator"> <return type="int" /> <description> + Returns the negated value of the [int]. If positive, turns the number negative. If negative, turns the number positive. If zero, does nothing. </description> </method> <method name="operator |" qualifiers="operator"> diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py index 6f9a07af1f..4691b61e1b 100755 --- a/doc/tools/makerst.py +++ b/doc/tools/makerst.py @@ -1031,9 +1031,6 @@ def make_enum(t, state): # type: (str, State) -> str if c in state.classes and e not in state.classes[c].enums: c = "@GlobalScope" - if not c in state.classes and c.startswith("_"): - c = c[1:] # Remove the underscore prefix - if c in state.classes and e in state.classes[c].enums: return ":ref:`{0}<enum_{1}_{0}>`".format(e, c) diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp index 56a9d2c258..8d1c22dabd 100644 --- a/editor/doc_tools.cpp +++ b/editor/doc_tools.cpp @@ -245,9 +245,6 @@ void DocTools::generate(bool p_basic_types) { } String cname = name; - if (cname.begins_with("_")) { //proxy class - cname = cname.substr(1, name.length()); - } class_list[cname] = DocData::ClassDoc(); DocData::ClassDoc &c = class_list[cname]; @@ -740,9 +737,6 @@ void DocTools::generate(bool p_basic_types) { while (String(ClassDB::get_parent_class(pd.type)) != "Object") { pd.type = ClassDB::get_parent_class(pd.type); } - if (pd.type.begins_with("_")) { - pd.type = pd.type.substr(1, pd.type.length()); - } c.properties.push_back(pd); } diff --git a/editor/editor_command_palette.cpp b/editor/editor_command_palette.cpp index 6349beeef4..cf6ede2277 100644 --- a/editor/editor_command_palette.cpp +++ b/editor/editor_command_palette.cpp @@ -70,8 +70,12 @@ void EditorCommandPalette::_update_command_search(const String &search_text) { r.key_name = command_keys[i]; r.display_name = commands[r.key_name].name; r.shortcut_text = commands[r.key_name].shortcut; + if (search_text.is_subsequence_ofi(r.display_name)) { - r.score = _score_path(search_text, r.display_name.to_lower()); + if (!search_text.is_empty()) { + r.score = _score_path(search_text, r.display_name.to_lower()); + } + entries.push_back(r); } } @@ -81,60 +85,55 @@ void EditorCommandPalette::_update_command_search(const String &search_text) { TreeItem *root = search_options->get_root(); root->clear_children(); - if (entries.size() > 0) { - if (!search_text.is_empty()) { - SortArray<CommandEntry, CommandEntryComparator> sorter; - sorter.sort(entries.ptrw(), entries.size()); - } + if (entries.is_empty()) { + get_ok_button()->set_disabled(true); - const int entry_limit = MIN(entries.size(), 300); - for (int i = 0; i < entry_limit; i++) { - String section_name = entries[i].key_name.get_slice("/", 0); - TreeItem *section; + return; + } - if (sections.has(section_name)) { - section = sections[section_name]; - } else { - section = search_options->create_item(root); + if (!search_text.is_empty()) { + SortArray<CommandEntry, CommandEntryComparator> sorter; + sorter.sort(entries.ptrw(), entries.size()); + } - if (!first_section) { - first_section = section; - } + const int entry_limit = MIN(entries.size(), 300); + for (int i = 0; i < entry_limit; i++) { + String section_name = entries[i].key_name.get_slice("/", 0); + TreeItem *section; - String item_name = section_name.capitalize(); - section->set_text(0, item_name); + if (sections.has(section_name)) { + section = sections[section_name]; + } else { + section = search_options->create_item(root); - sections[section_name] = section; - section->set_custom_bg_color(0, search_options->get_theme_color("prop_subsection", "Editor")); - section->set_custom_bg_color(1, search_options->get_theme_color("prop_subsection", "Editor")); + if (!first_section) { + first_section = section; } - TreeItem *ti = search_options->create_item(section); - String shortcut_text = entries[i].shortcut_text == "None" ? "" : entries[i].shortcut_text; - ti->set_text(0, entries[i].display_name); - ti->set_metadata(0, entries[i].key_name); - ti->set_text_align(1, TreeItem::TextAlign::ALIGN_RIGHT); - ti->set_text(1, shortcut_text); - Color c = Color(1, 1, 1, 0.5); - ti->set_custom_color(1, c); - } - - TreeItem *to_select = first_section->get_first_child(); - to_select->select(0); - to_select->set_as_cursor(0); - search_options->scroll_to_item(to_select); + String item_name = section_name.capitalize(); + section->set_text(0, item_name); + section->set_selectable(0, false); + section->set_selectable(1, false); + section->set_custom_bg_color(0, search_options->get_theme_color("prop_subsection", "Editor")); + section->set_custom_bg_color(1, search_options->get_theme_color("prop_subsection", "Editor")); - get_ok_button()->set_disabled(false); - } else { - TreeItem *ti = search_options->create_item(root); - ti->set_text(0, TTR("No matching commands found")); - ti->set_metadata(0, ""); - Color c = Color(0.5, 0.5, 0.5, 0.5); - ti->set_custom_color(0, c); - search_options->deselect_all(); + sections[section_name] = section; + } - get_ok_button()->set_disabled(true); + TreeItem *ti = search_options->create_item(section); + String shortcut_text = entries[i].shortcut_text == "None" ? "" : entries[i].shortcut_text; + ti->set_text(0, entries[i].display_name); + ti->set_metadata(0, entries[i].key_name); + ti->set_text_align(1, TreeItem::TextAlign::ALIGN_RIGHT); + ti->set_text(1, shortcut_text); + Color c = Color(1, 1, 1, 0.5); + ti->set_custom_color(1, c); } + + TreeItem *to_select = first_section->get_first_child(); + to_select->select(0); + to_select->set_as_cursor(0); + search_options->ensure_cursor_is_visible(); } void EditorCommandPalette::_bind_methods() { @@ -169,8 +168,11 @@ void EditorCommandPalette::_confirmed() { void EditorCommandPalette::open_popup() { popup_centered_clamped(Size2i(600, 440), 0.8f); + command_search_box->clear(); command_search_box->grab_focus(); + + search_options->scroll_to_item(search_options->get_root()); } void EditorCommandPalette::get_actions_list(List<String> *p_list) const { @@ -258,6 +260,9 @@ EditorCommandPalette *EditorCommandPalette::get_singleton() { } EditorCommandPalette::EditorCommandPalette() { + set_hide_on_ok(false); + connect("confirmed", callable_mp(this, &EditorCommandPalette::_confirmed)); + VBoxContainer *vbc = memnew(VBoxContainer); vbc->connect("theme_changed", callable_mp(this, &EditorCommandPalette::_theme_changed)); add_child(vbc); @@ -275,18 +280,15 @@ EditorCommandPalette::EditorCommandPalette() { search_options = memnew(Tree); search_options->connect("item_activated", callable_mp(this, &EditorCommandPalette::_confirmed)); + search_options->connect("item_selected", callable_mp((BaseButton *)get_ok_button(), &BaseButton::set_disabled), varray(false)); + search_options->connect("nothing_selected", callable_mp((BaseButton *)get_ok_button(), &BaseButton::set_disabled), varray(true)); search_options->create_item(); search_options->set_hide_root(true); - search_options->set_hide_folding(true); - search_options->add_theme_constant_override("draw_guides", 1); search_options->set_columns(2); search_options->set_v_size_flags(Control::SIZE_EXPAND_FILL); search_options->set_h_size_flags(Control::SIZE_EXPAND_FILL); search_options->set_column_custom_minimum_width(0, int(8 * EDSCALE)); vbc->add_child(search_options, true); - - connect("confirmed", callable_mp(this, &EditorCommandPalette::_confirmed)); - set_hide_on_ok(false); } Ref<Shortcut> ED_SHORTCUT_AND_COMMAND(const String &p_path, const String &p_name, Key p_keycode, String p_command_name) { diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 9de8b0451a..b3ce11028b 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -2243,6 +2243,13 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo undo_redo->add_do_property(object, p_name, p_value); undo_redo->add_undo_property(object, p_name, object->get(p_name)); + PropertyInfo prop_info; + if (ClassDB::get_property_info(object->get_class_name(), p_name, &prop_info)) { + for (const String &linked_prop : prop_info.linked_properties) { + undo_redo->add_undo_property(object, linked_prop, object->get(linked_prop)); + } + } + Variant v_undo_redo = (Object *)undo_redo; Variant v_object = object; Variant v_name = p_name; diff --git a/editor/import/collada.cpp b/editor/import/collada.cpp index aa9700716d..71930e1e59 100644 --- a/editor/import/collada.cpp +++ b/editor/import/collada.cpp @@ -960,6 +960,7 @@ void Collada::_parse_mesh_geometry(XMLParser &parser, String p_id, String p_name } else if (section == "vertices") { MeshData::Vertices vert; String id = parser.get_attribute_value("id"); + int last_ref = 0; while (parser.read() == OK) { if (parser.get_node_type() == XMLParser::NODE_ELEMENT) { @@ -967,6 +968,10 @@ void Collada::_parse_mesh_geometry(XMLParser &parser, String p_id, String p_name String semantic = parser.get_attribute_value("semantic"); String source = _uri_to_id(parser.get_attribute_value("source")); + if (semantic == "TEXCOORD") { + semantic = "TEXCOORD" + itos(last_ref++); + } + vert.sources[semantic] = source; COLLADA_PRINT(section + " input semantic: " + semantic + " source: " + source); diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp index 54b93edcdd..7ab80ac3b4 100644 --- a/editor/import/editor_import_collada.cpp +++ b/editor/import/editor_import_collada.cpp @@ -504,61 +504,121 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<EditorSceneImpor const Collada::MeshData::Source *normal_src = nullptr; int normal_ofs = 0; - if (p.sources.has("NORMAL")) { - String normal_source_id = p.sources["NORMAL"].source; - normal_ofs = p.sources["NORMAL"].offset; - ERR_FAIL_COND_V(!meshdata.sources.has(normal_source_id), ERR_INVALID_DATA); - normal_src = &meshdata.sources[normal_source_id]; + { + String normal_source_id = ""; + + if (p.sources.has("NORMAL")) { + normal_source_id = p.sources["NORMAL"].source; + normal_ofs = p.sources["NORMAL"].offset; + } else if (meshdata.vertices[vertex_src_id].sources.has("NORMAL")) { + normal_source_id = meshdata.vertices[vertex_src_id].sources["NORMAL"]; + normal_ofs = vertex_ofs; + } + + if (normal_source_id != "") { + ERR_FAIL_COND_V(!meshdata.sources.has(normal_source_id), ERR_INVALID_DATA); + normal_src = &meshdata.sources[normal_source_id]; + } } const Collada::MeshData::Source *binormal_src = nullptr; int binormal_ofs = 0; - if (p.sources.has("TEXBINORMAL")) { - String binormal_source_id = p.sources["TEXBINORMAL"].source; - binormal_ofs = p.sources["TEXBINORMAL"].offset; - ERR_FAIL_COND_V(!meshdata.sources.has(binormal_source_id), ERR_INVALID_DATA); - binormal_src = &meshdata.sources[binormal_source_id]; + { + String binormal_source_id = ""; + + if (p.sources.has("TEXBINORMAL")) { + binormal_source_id = p.sources["TEXBINORMAL"].source; + binormal_ofs = p.sources["TEXBINORMAL"].offset; + } else if (meshdata.vertices[vertex_src_id].sources.has("TEXBINORMAL")) { + binormal_source_id = meshdata.vertices[vertex_src_id].sources["TEXBINORMAL"]; + binormal_ofs = vertex_ofs; + } + + if (binormal_source_id != "") { + ERR_FAIL_COND_V(!meshdata.sources.has(binormal_source_id), ERR_INVALID_DATA); + binormal_src = &meshdata.sources[binormal_source_id]; + } } const Collada::MeshData::Source *tangent_src = nullptr; int tangent_ofs = 0; - if (p.sources.has("TEXTANGENT")) { - String tangent_source_id = p.sources["TEXTANGENT"].source; - tangent_ofs = p.sources["TEXTANGENT"].offset; - ERR_FAIL_COND_V(!meshdata.sources.has(tangent_source_id), ERR_INVALID_DATA); - tangent_src = &meshdata.sources[tangent_source_id]; + { + String tangent_source_id = ""; + + if (p.sources.has("TEXTANGENT")) { + tangent_source_id = p.sources["TEXTANGENT"].source; + tangent_ofs = p.sources["TEXTANGENT"].offset; + } else if (meshdata.vertices[vertex_src_id].sources.has("TEXTANGENT")) { + tangent_source_id = meshdata.vertices[vertex_src_id].sources["TEXTANGENT"]; + tangent_ofs = vertex_ofs; + } + + if (tangent_source_id != "") { + ERR_FAIL_COND_V(!meshdata.sources.has(tangent_source_id), ERR_INVALID_DATA); + tangent_src = &meshdata.sources[tangent_source_id]; + } } const Collada::MeshData::Source *uv_src = nullptr; int uv_ofs = 0; - if (p.sources.has("TEXCOORD0")) { - String uv_source_id = p.sources["TEXCOORD0"].source; - uv_ofs = p.sources["TEXCOORD0"].offset; - ERR_FAIL_COND_V(!meshdata.sources.has(uv_source_id), ERR_INVALID_DATA); - uv_src = &meshdata.sources[uv_source_id]; + { + String uv_source_id = ""; + + if (p.sources.has("TEXCOORD0")) { + uv_source_id = p.sources["TEXCOORD0"].source; + uv_ofs = p.sources["TEXCOORD0"].offset; + } else if (meshdata.vertices[vertex_src_id].sources.has("TEXCOORD0")) { + uv_source_id = meshdata.vertices[vertex_src_id].sources["TEXCOORD0"]; + uv_ofs = vertex_ofs; + } + + if (uv_source_id != "") { + ERR_FAIL_COND_V(!meshdata.sources.has(uv_source_id), ERR_INVALID_DATA); + uv_src = &meshdata.sources[uv_source_id]; + } } const Collada::MeshData::Source *uv2_src = nullptr; int uv2_ofs = 0; - if (p.sources.has("TEXCOORD1")) { - String uv2_source_id = p.sources["TEXCOORD1"].source; - uv2_ofs = p.sources["TEXCOORD1"].offset; - ERR_FAIL_COND_V(!meshdata.sources.has(uv2_source_id), ERR_INVALID_DATA); - uv2_src = &meshdata.sources[uv2_source_id]; + { + String uv2_source_id = ""; + + if (p.sources.has("TEXCOORD1")) { + uv2_source_id = p.sources["TEXCOORD1"].source; + uv2_ofs = p.sources["TEXCOORD1"].offset; + } else if (meshdata.vertices[vertex_src_id].sources.has("TEXCOORD1")) { + uv2_source_id = meshdata.vertices[vertex_src_id].sources["TEXCOORD1"]; + uv2_ofs = vertex_ofs; + } + + if (uv2_source_id != "") { + ERR_FAIL_COND_V(!meshdata.sources.has(uv2_source_id), ERR_INVALID_DATA); + uv2_src = &meshdata.sources[uv2_source_id]; + } } const Collada::MeshData::Source *color_src = nullptr; int color_ofs = 0; - if (p.sources.has("COLOR")) { - String color_source_id = p.sources["COLOR"].source; - color_ofs = p.sources["COLOR"].offset; - ERR_FAIL_COND_V(!meshdata.sources.has(color_source_id), ERR_INVALID_DATA); - color_src = &meshdata.sources[color_source_id]; + { + String color_source_id = ""; + + if (p.sources.has("COLOR")) { + color_source_id = p.sources["COLOR"].source; + color_ofs = p.sources["COLOR"].offset; + } else if (meshdata.vertices[vertex_src_id].sources.has("COLOR")) { + color_source_id = meshdata.vertices[vertex_src_id].sources["COLOR"]; + color_ofs = vertex_ofs; + } + + if (color_source_id != "") { + ERR_FAIL_COND_V(!meshdata.sources.has(color_source_id), ERR_INVALID_DATA); + color_src = &meshdata.sources[color_source_id]; + } } //find largest source.. diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index 69206daea8..030d90eeca 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -126,6 +126,7 @@ void AnimationNodeBlendTreeEditor::_update_graph() { graph->add_child(node); Ref<AnimationNode> agnode = blend_tree->get_node(E); + ERR_CONTINUE(!agnode.is_valid()); node->set_position_offset(blend_tree->get_node_position(E) * EDSCALE); diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp index 486f947e43..c2684305ef 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.cpp +++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp @@ -50,12 +50,7 @@ Variant CollisionShape2DEditor::get_handle_value(int idx) const { switch (shape_type) { case CAPSULE_SHAPE: { Ref<CapsuleShape2D> capsule = node->get_shape(); - - if (idx == 0) { - return capsule->get_radius(); - } else if (idx == 1) { - return capsule->get_height(); - } + return Vector2(capsule->get_radius(), capsule->get_height()); } break; @@ -209,17 +204,17 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { case CAPSULE_SHAPE: { Ref<CapsuleShape2D> capsule = node->get_shape(); + Vector2 values = p_org; + if (idx == 0) { undo_redo->add_do_method(capsule.ptr(), "set_radius", capsule->get_radius()); - undo_redo->add_do_method(canvas_item_editor, "update_viewport"); - undo_redo->add_undo_method(capsule.ptr(), "set_radius", p_org); - undo_redo->add_do_method(canvas_item_editor, "update_viewport"); } else if (idx == 1) { undo_redo->add_do_method(capsule.ptr(), "set_height", capsule->get_height()); - undo_redo->add_do_method(canvas_item_editor, "update_viewport"); - undo_redo->add_undo_method(capsule.ptr(), "set_height", p_org); - undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); } + undo_redo->add_do_method(canvas_item_editor, "update_viewport"); + undo_redo->add_undo_method(capsule.ptr(), "set_radius", values[0]); + undo_redo->add_undo_method(capsule.ptr(), "set_height", values[1]); + undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); } break; diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp index 38510ff81e..a42f94ed3d 100644 --- a/editor/plugins/node_3d_editor_gizmos.cpp +++ b/editor/plugins/node_3d_editor_gizmos.cpp @@ -4114,7 +4114,7 @@ Variant CollisionShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p if (Object::cast_to<CapsuleShape3D>(*s)) { Ref<CapsuleShape3D> cs2 = s; - return p_id == 0 ? cs2->get_radius() : cs2->get_height(); + return Vector2(cs2->get_radius(), cs2->get_height()); } if (Object::cast_to<CylinderShape3D>(*s)) { @@ -4261,12 +4261,11 @@ void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo if (Object::cast_to<CapsuleShape3D>(*s)) { Ref<CapsuleShape3D> ss = s; + Vector2 values = p_restore; + if (p_cancel) { - if (p_id == 0) { - ss->set_radius(p_restore); - } else { - ss->set_height(p_restore); - } + ss->set_radius(values[0]); + ss->set_height(values[1]); return; } @@ -4274,12 +4273,12 @@ void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo if (p_id == 0) { ur->create_action(TTR("Change Capsule Shape Radius")); ur->add_do_method(ss.ptr(), "set_radius", ss->get_radius()); - ur->add_undo_method(ss.ptr(), "set_radius", p_restore); } else { ur->create_action(TTR("Change Capsule Shape Height")); ur->add_do_method(ss.ptr(), "set_height", ss->get_height()); - ur->add_undo_method(ss.ptr(), "set_height", p_restore); } + ur->add_undo_method(ss.ptr(), "set_radius", values[0]); + ur->add_undo_method(ss.ptr(), "set_height", values[1]); ur->commit_action(); } diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index bd90fa82f2..5c1e557286 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -104,11 +104,7 @@ void EditorStandardSyntaxHighlighter::_update_cache() { List<StringName> types; ClassDB::get_class_list(&types); for (const StringName &E : types) { - String n = E; - if (n.begins_with("_")) { - n = n.substr(1, n.length()); - } - highlighter->add_keyword_color(n, type_color); + highlighter->add_keyword_color(E, type_color); } /* User types. */ diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 7f2908eada..5f48106afc 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -758,8 +758,6 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c } else if (script->get_language()->lookup_code(code_editor->get_text_editor()->get_text_for_symbol_lookup(), p_symbol, script->get_path(), base, result) == OK) { _goto_line(p_row); - result.class_name = result.class_name.trim_prefix("_"); - switch (result.type) { case ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION: { if (result.script.is_valid()) { diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 2dd8270ee3..d84ed4828c 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -1219,8 +1219,88 @@ void VisualShaderEditor::_update_options_menu() { Vector<AddOption> custom_options; Vector<AddOption> embedded_options; + static Vector<String> type_filter_exceptions; + if (type_filter_exceptions.is_empty()) { + type_filter_exceptions.append("VisualShaderNodeExpression"); + } + for (int i = 0; i < add_options.size(); i++) { if (!use_filter || add_options[i].name.findn(filter) != -1) { + // port type filtering + if (members_output_port_type != VisualShaderNode::PORT_TYPE_MAX || members_input_port_type != VisualShaderNode::PORT_TYPE_MAX) { + Ref<VisualShaderNode> vsn; + int check_result = 0; + + if (!add_options[i].is_custom) { + vsn = Ref<VisualShaderNode>(Object::cast_to<VisualShaderNode>(ClassDB::instantiate(add_options[i].type))); + if (!vsn.is_valid()) { + continue; + } + + if (type_filter_exceptions.has(add_options[i].type)) { + check_result = 1; + } + + Ref<VisualShaderNodeInput> input = Object::cast_to<VisualShaderNodeInput>(vsn.ptr()); + if (input.is_valid()) { + input->set_shader_mode(visual_shader->get_mode()); + input->set_shader_type(visual_shader->get_shader_type()); + input->set_input_name(add_options[i].sub_func_str); + } + + Ref<VisualShaderNodeExpression> expression = Object::cast_to<VisualShaderNodeExpression>(vsn.ptr()); + if (expression.is_valid()) { + if (members_input_port_type == VisualShaderNode::PORT_TYPE_SAMPLER) { + check_result = -1; // expressions creates a port with required type automatically (except for sampler output) + } + } + + Ref<VisualShaderNodeUniformRef> uniform_ref = Object::cast_to<VisualShaderNodeUniformRef>(vsn.ptr()); + if (uniform_ref.is_valid()) { + check_result = -1; + + if (members_input_port_type != VisualShaderNode::PORT_TYPE_MAX) { + for (int j = 0; j < uniform_ref->get_uniforms_count(); j++) { + if (visual_shader->is_port_types_compatible(uniform_ref->get_port_type_by_index(j), members_input_port_type)) { + check_result = 1; + break; + } + } + } + } + } else { + check_result = 1; + } + + if (members_output_port_type != VisualShaderNode::PORT_TYPE_MAX) { + if (check_result == 0) { + for (int j = 0; j < vsn->get_input_port_count(); j++) { + if (visual_shader->is_port_types_compatible(vsn->get_input_port_type(j), members_output_port_type)) { + check_result = 1; + break; + } + } + } + + if (check_result != 1) { + continue; + } + } + if (members_input_port_type != VisualShaderNode::PORT_TYPE_MAX) { + if (check_result == 0) { + for (int j = 0; j < vsn->get_output_port_count(); j++) { + if (visual_shader->is_port_types_compatible(vsn->get_output_port_type(j), members_input_port_type)) { + check_result = 1; + break; + } + } + } + + if (check_result != 1) { + continue; + } + } + } if ((add_options[i].func != current_func && add_options[i].func != -1) || !_is_available(add_options[i].mode)) { continue; } @@ -2588,13 +2668,25 @@ void VisualShaderEditor::_disconnection_request(const String &p_from, int p_from void VisualShaderEditor::_connection_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_position) { from_node = p_from.to_int(); from_slot = p_from_slot; - _show_members_dialog(true); + VisualShaderNode::PortType input_port_type = VisualShaderNode::PORT_TYPE_MAX; + VisualShaderNode::PortType output_port_type = VisualShaderNode::PORT_TYPE_MAX; + Ref<VisualShaderNode> node = visual_shader->get_node(get_current_shader_type(), from_node); + if (node.is_valid()) { + output_port_type = node->get_output_port_type(from_slot); + } + _show_members_dialog(true, input_port_type, output_port_type); } void VisualShaderEditor::_connection_from_empty(const String &p_to, int p_to_slot, const Vector2 &p_release_position) { to_node = p_to.to_int(); to_slot = p_to_slot; - _show_members_dialog(true); + VisualShaderNode::PortType input_port_type = VisualShaderNode::PORT_TYPE_MAX; + VisualShaderNode::PortType output_port_type = VisualShaderNode::PORT_TYPE_MAX; + Ref<VisualShaderNode> node = visual_shader->get_node(get_current_shader_type(), to_node); + if (node.is_valid()) { + input_port_type = node->get_input_port_type(to_slot); + } + _show_members_dialog(true, input_port_type, output_port_type); } void VisualShaderEditor::_delete_nodes(int p_type, const List<int> &p_nodes) { @@ -3036,7 +3128,13 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { } } -void VisualShaderEditor::_show_members_dialog(bool at_mouse_pos) { +void VisualShaderEditor::_show_members_dialog(bool at_mouse_pos, VisualShaderNode::PortType p_input_port_type, VisualShaderNode::PortType p_output_port_type) { + if (members_input_port_type != p_input_port_type || members_output_port_type != p_output_port_type) { + members_input_port_type = p_input_port_type; + members_output_port_type = p_output_port_type; + _update_options_menu(); + } + if (at_mouse_pos) { saved_node_pos_dirty = true; saved_node_pos = graph->get_local_mouse_position(); @@ -3114,7 +3212,7 @@ void VisualShaderEditor::_notification(int p_what) { { Color background_color = EDITOR_GET("text_editor/theme/highlighting/background_color"); Color text_color = EDITOR_GET("text_editor/theme/highlighting/text_color"); - Color keyword_color = EDITOR_GET("text_editor/highlighting/keyword_color"); + Color keyword_color = EDITOR_GET("text_editor/theme/highlighting/keyword_color"); Color control_flow_keyword_color = EDITOR_GET("text_editor/theme/highlighting/control_flow_keyword_color"); Color comment_color = EDITOR_GET("text_editor/theme/highlighting/comment_color"); Color symbol_color = EDITOR_GET("text_editor/theme/highlighting/symbol_color"); diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 87bab16a45..fbfe1197a3 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -160,6 +160,8 @@ class VisualShaderEditor : public VBoxContainer { bool saved_node_pos_dirty; ConfirmationDialog *members_dialog; + VisualShaderNode::PortType members_input_port_type = VisualShaderNode::PORT_TYPE_MAX; + VisualShaderNode::PortType members_output_port_type = VisualShaderNode::PORT_TYPE_MAX; PopupMenu *popup_menu; PopupMenu *constants_submenu = nullptr; MenuButton *tools; @@ -227,7 +229,7 @@ class VisualShaderEditor : public VBoxContainer { Label *highend_label; void _tools_menu_option(int p_idx); - void _show_members_dialog(bool at_mouse_pos); + void _show_members_dialog(bool at_mouse_pos, VisualShaderNode::PortType p_input_port_type = VisualShaderNode::PORT_TYPE_MAX, VisualShaderNode::PortType p_output_port_type = VisualShaderNode::PORT_TYPE_MAX); void _update_graph(); diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp index ee100ca938..71802d1737 100644 --- a/editor/settings_config_dialog.cpp +++ b/editor/settings_config_dialog.cpp @@ -250,6 +250,8 @@ void EditorSettingsDialog::_update_shortcuts() { sections["Common"] = common_section; common_section->set_text(0, TTR("Common")); + common_section->set_selectable(0, false); + common_section->set_selectable(1, false); if (collapsed.has("Common")) { common_section->set_collapsed(collapsed["Common"]); } @@ -343,14 +345,16 @@ void EditorSettingsDialog::_update_shortcuts() { String item_name = section_name.capitalize(); section->set_text(0, item_name); + section->set_selectable(0, false); + section->set_selectable(1, false); + section->set_custom_bg_color(0, shortcuts->get_theme_color(SNAME("prop_subsection"), SNAME("Editor"))); + section->set_custom_bg_color(1, shortcuts->get_theme_color(SNAME("prop_subsection"), SNAME("Editor"))); if (collapsed.has(item_name)) { section->set_collapsed(collapsed[item_name]); } sections[section_name] = section; - section->set_custom_bg_color(0, shortcuts->get_theme_color(SNAME("prop_subsection"), SNAME("Editor"))); - section->set_custom_bg_color(1, shortcuts->get_theme_color(SNAME("prop_subsection"), SNAME("Editor"))); } // Don't match unassigned shortcuts when searching for assigned keys in search results. diff --git a/methods.py b/methods.py index 970bd10aa3..86a802bf5f 100644 --- a/methods.py +++ b/methods.py @@ -934,9 +934,12 @@ def show_progress(env): def progress_finish(target, source, env): nonlocal node_count, progressor - with open(node_count_fname, "w") as f: - f.write("%d\n" % node_count) - progressor.delete(progressor.file_list()) + try: + with open(node_count_fname, "w") as f: + f.write("%d\n" % node_count) + progressor.delete(progressor.file_list()) + except Exception: + pass try: with open(node_count_fname) as f: diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index c6d835742d..a9a811c445 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -945,6 +945,11 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform3D &p G_TO_B(p_from, body_transform); UNSCALE_BT_BASIS(body_transform); + if (!p_body->get_kinematic_utilities()) { + p_body->init_kinematic_utilities(); + p_body->reload_kinematic_shapes(); + } + btVector3 initial_recover_motion(0, 0, 0); { /// Phase one - multi shapes depenetration using margin for (int t(RECOVERING_MOVEMENT_CYCLES); 0 < t; --t) { @@ -958,6 +963,9 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform3D &p btVector3 motion; G_TO_B(p_motion, motion); + real_t total_length = motion.length(); + real_t unsafe_fraction = 1.0; + real_t safe_fraction = 1.0; { // Phase two - sweep test, from a secure position without margin @@ -1007,6 +1015,15 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform3D &p dynamicsWorld->convexSweepTest(convex_shape_test, shape_world_from, shape_world_to, btResult, dynamicsWorld->getDispatchInfo().m_allowedCcdPenetration); if (btResult.hasHit()) { + if (total_length > CMP_EPSILON) { + real_t hit_fraction = btResult.m_closestHitFraction * motion.length() / total_length; + if (hit_fraction < unsafe_fraction) { + unsafe_fraction = hit_fraction; + real_t margin = p_body->get_kinematic_utilities()->safe_margin; + safe_fraction = MAX(hit_fraction - (1 - ((total_length - margin) / total_length)), 0); + } + } + /// Since for each sweep test I fix the motion of new shapes in base the recover result, /// if another shape will hit something it means that has a deepest penetration respect the previous shape motion *= btResult.m_closestHitFraction; @@ -1043,6 +1060,9 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform3D &p r_result->collider_id = collisionObject->get_instance_id(); r_result->collider_shape = r_recover_result.other_compound_shape_index; r_result->collision_local_shape = r_recover_result.local_shape_most_recovered; + r_result->collision_depth = Math::abs(r_recover_result.penetration_distance); + r_result->collision_safe_fraction = safe_fraction; + r_result->collision_unsafe_fraction = unsafe_fraction; #if debug_test_motion Vector3 sup_line2; @@ -1067,6 +1087,11 @@ int SpaceBullet::test_ray_separation(RigidBodyBullet *p_body, const Transform3D G_TO_B(p_transform, body_transform); UNSCALE_BT_BASIS(body_transform); + if (!p_body->get_kinematic_utilities()) { + p_body->init_kinematic_utilities(); + p_body->reload_kinematic_shapes(); + } + btVector3 recover_motion(0, 0, 0); int rays_found = 0; diff --git a/modules/fbx/data/fbx_material.cpp b/modules/fbx/data/fbx_material.cpp index fb6c67f7b9..86baec4244 100644 --- a/modules/fbx/data/fbx_material.cpp +++ b/modules/fbx/data/fbx_material.cpp @@ -31,7 +31,7 @@ #include "fbx_material.h" // FIXME: Shouldn't depend on core_bind.h! Use DirAccessRef like the rest of -// the engine instead of _Directory. +// the engine instead of core_bind::Directory. #include "core/core_bind.h" #include "scene/resources/material.h" #include "scene/resources/texture.h" @@ -55,7 +55,7 @@ void FBXMaterial::add_search_string(String p_filename, String p_current_director } String find_file(const String &p_base, const String &p_file_to_find) { - _Directory dir; + core_bind::Directory dir; dir.open(p_base); dir.list_dir_begin(); @@ -84,7 +84,7 @@ String find_file(const String &p_base, const String &p_file_to_find) { // fbx will not give us good path information and let's not regex them to fix them // no relative paths are in fbx generally they have a rel field but it's populated incorrectly by the SDK. String FBXMaterial::find_texture_path_by_filename(const String p_filename, const String p_current_directory) { - _Directory dir; + core_bind::Directory dir; Vector<String> paths; add_search_string(p_filename, p_current_directory, "", paths); add_search_string(p_filename, p_current_directory, "texture", paths); diff --git a/modules/gdnative/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp index df0f29277e..2d9b45cb07 100644 --- a/modules/gdnative/nativescript/api_generator.cpp +++ b/modules/gdnative/nativescript/api_generator.cpp @@ -242,13 +242,9 @@ List<ClassAPI> generate_c_api_classes() { class_api.class_name = class_name; class_api.super_class_name = ClassDB::get_parent_class(class_name); { - String name = class_name; - if (name.begins_with("_")) { - name.remove(0); - } - class_api.is_singleton = Engine::get_singleton()->has_singleton(name); + class_api.is_singleton = Engine::get_singleton()->has_singleton(class_name); if (class_api.is_singleton) { - class_api.singleton_name = name; + class_api.singleton_name = class_name; } } class_api.is_instantiable = !class_api.is_singleton && ClassDB::can_instantiate(class_name); diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp index 3441233811..0b1cb5d502 100644 --- a/modules/gdscript/editor/gdscript_highlighter.cpp +++ b/modules/gdscript/editor/gdscript_highlighter.cpp @@ -459,11 +459,7 @@ void GDScriptSyntaxHighlighter::_update_cache() { List<StringName> types; ClassDB::get_class_list(&types); for (const StringName &E : types) { - String n = E; - if (n.begins_with("_")) { - n = n.substr(1, n.length()); - } - keywords[n] = types_color; + keywords[E] = types_color; } /* User types. */ diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 8957b00a1b..4589cf1a36 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -1644,16 +1644,11 @@ void GDScriptLanguage::init() { List<StringName> class_list; ClassDB::get_class_list(&class_list); for (const StringName &n : class_list) { - String s = String(n); - if (s.begins_with("_")) { - s = s.substr(1, s.length()); - } - - if (globals.has(s)) { + if (globals.has(n)) { continue; } Ref<GDScriptNativeClass> nc = memnew(GDScriptNativeClass(n)); - _add_global(s, nc); + _add_global(n, nc); } //populate singletons diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index ab37e54cf1..e925350ba3 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -112,11 +112,10 @@ static GDScriptParser::DataType make_native_enum_type(const StringName &p_native type.is_meta_type = true; List<StringName> enum_values; - StringName real_native_name = GDScriptParser::get_real_class_name(p_native_class); - ClassDB::get_enum_constants(real_native_name, p_enum_name, &enum_values); + ClassDB::get_enum_constants(p_native_class, p_enum_name, &enum_values); for (const StringName &E : enum_values) { - type.enum_values[E] = ClassDB::get_integer_constant(real_native_name, E); + type.enum_values[E] = ClassDB::get_integer_constant(p_native_class, E); } return type; @@ -229,7 +228,7 @@ Error GDScriptAnalyzer::resolve_inheritance(GDScriptParser::ClassNode *p_class, push_error(vformat(R"(Could not resolve super class inheritance from "%s".)", name), p_class); return err; } - } else if (class_exists(name) && ClassDB::can_instantiate(GDScriptParser::get_real_class_name(name))) { + } else if (class_exists(name) && ClassDB::can_instantiate(name)) { base.kind = GDScriptParser::DataType::NATIVE; base.native_type = name; } else { @@ -406,7 +405,7 @@ GDScriptParser::DataType GDScriptAnalyzer::resolve_datatype(GDScriptParser::Type return GDScriptParser::DataType(); } result = ref->get_parser()->head->get_datatype(); - } else if (ClassDB::has_enum(GDScriptParser::get_real_class_name(parser->current_class->base_type.native_type), first)) { + } else if (ClassDB::has_enum(parser->current_class->base_type.native_type, first)) { // Native enum in current class. result = make_native_enum_type(parser->current_class->base_type.native_type, first); } else { @@ -469,7 +468,7 @@ GDScriptParser::DataType GDScriptAnalyzer::resolve_datatype(GDScriptParser::Type } } else if (result.kind == GDScriptParser::DataType::NATIVE) { // Only enums allowed for native. - if (ClassDB::has_enum(GDScriptParser::get_real_class_name(result.native_type), p_type->type_chain[1]->name)) { + if (ClassDB::has_enum(result.native_type, p_type->type_chain[1]->name)) { if (p_type->type_chain.size() > 2) { push_error(R"(Enums cannot contain nested types.)", p_type->type_chain[2]); } else { @@ -2252,7 +2251,7 @@ void GDScriptAnalyzer::reduce_get_node(GDScriptParser::GetNodeNode *p_get_node) result.native_type = "Node"; result.builtin_type = Variant::OBJECT; - if (!ClassDB::is_parent_class(GDScriptParser::get_real_class_name(parser->current_class->base_type.native_type), result.native_type)) { + if (!ClassDB::is_parent_class(parser->current_class->base_type.native_type, result.native_type)) { push_error(R"*(Cannot use shorthand "get_node()" notation ("$") on a class that isn't a node.)*", p_get_node); } else if (!lambda_stack.is_empty()) { push_error(R"*(Cannot use shorthand "get_node()" notation ("$") inside a lambda. Use a captured variable instead.)*", p_get_node); @@ -2421,7 +2420,7 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod } // Check native members. - const StringName &native = GDScriptParser::get_real_class_name(base.native_type); + const StringName &native = base.native_type; if (class_exists(native)) { PropertyInfo prop_info; @@ -3303,10 +3302,8 @@ bool GDScriptAnalyzer::get_function_signature(GDScriptParser::Node *p_source, GD return true; } - StringName real_native = GDScriptParser::get_real_class_name(base_native); - MethodInfo info; - if (ClassDB::get_method_info(real_native, function_name, &info)) { + if (ClassDB::get_method_info(base_native, function_name, &info)) { return function_signature_from_info(info, r_return_type, r_par_types, r_default_arg_count, r_static, r_vararg); } @@ -3398,24 +3395,23 @@ bool GDScriptAnalyzer::is_shadowing(GDScriptParser::IdentifierNode *p_local, con StringName parent = base_native; while (parent != StringName()) { - StringName real_class_name = GDScriptParser::get_real_class_name(parent); - if (ClassDB::has_method(real_class_name, name, true)) { + if (ClassDB::has_method(parent, name, true)) { parser->push_warning(p_local, GDScriptWarning::SHADOWED_VARIABLE_BASE_CLASS, p_context, p_local->name, "method", parent); return true; - } else if (ClassDB::has_signal(real_class_name, name, true)) { + } else if (ClassDB::has_signal(parent, name, true)) { parser->push_warning(p_local, GDScriptWarning::SHADOWED_VARIABLE_BASE_CLASS, p_context, p_local->name, "signal", parent); return true; - } else if (ClassDB::has_property(real_class_name, name, true)) { + } else if (ClassDB::has_property(parent, name, true)) { parser->push_warning(p_local, GDScriptWarning::SHADOWED_VARIABLE_BASE_CLASS, p_context, p_local->name, "property", parent); return true; - } else if (ClassDB::has_integer_constant(real_class_name, name, true)) { + } else if (ClassDB::has_integer_constant(parent, name, true)) { parser->push_warning(p_local, GDScriptWarning::SHADOWED_VARIABLE_BASE_CLASS, p_context, p_local->name, "constant", parent); return true; - } else if (ClassDB::has_enum(real_class_name, name, true)) { + } else if (ClassDB::has_enum(parent, name, true)) { parser->push_warning(p_local, GDScriptWarning::SHADOWED_VARIABLE_BASE_CLASS, p_context, p_local->name, "enum", parent); return true; } - parent = ClassDB::get_parent_class(real_class_name); + parent = ClassDB::get_parent_class(parent); } return false; @@ -3560,16 +3556,12 @@ bool GDScriptAnalyzer::is_type_compatible(const GDScriptParser::DataType &p_targ break; // Already solved before. } - // Get underscore-prefixed version for some classes. - src_native = GDScriptParser::get_real_class_name(src_native); - switch (p_target.kind) { case GDScriptParser::DataType::NATIVE: { if (p_target.is_meta_type) { return ClassDB::is_parent_class(src_native, GDScriptNativeClass::get_class_static()); } - StringName tgt_native = GDScriptParser::get_real_class_name(p_target.native_type); - return ClassDB::is_parent_class(src_native, tgt_native); + return ClassDB::is_parent_class(src_native, p_target.native_type); } case GDScriptParser::DataType::SCRIPT: if (p_target.is_meta_type) { @@ -3618,8 +3610,7 @@ void GDScriptAnalyzer::mark_node_unsafe(const GDScriptParser::Node *p_node) { } bool GDScriptAnalyzer::class_exists(const StringName &p_class) const { - StringName real_name = GDScriptParser::get_real_class_name(p_class); - return ClassDB::class_exists(real_name) && ClassDB::is_class_exposed(real_name); + return ClassDB::class_exists(p_class) && ClassDB::is_class_exposed(p_class); } Ref<GDScriptParserRef> GDScriptAnalyzer::get_parser_for(const String &p_path) { diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 73661855b4..372a726d71 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -912,7 +912,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base } } break; case GDScriptParser::DataType::NATIVE: { - StringName type = GDScriptParser::get_real_class_name(base_type.native_type); + StringName type = base_type.native_type; if (!ClassDB::class_exists(type)) { return; } @@ -1326,10 +1326,7 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context, native_type.kind = GDScriptParser::DataType::NATIVE; native_type.native_type = native_type.script_type->get_instance_base_type(); if (!ClassDB::class_exists(native_type.native_type)) { - native_type.native_type = String("_") + native_type.native_type; - if (!ClassDB::class_exists(native_type.native_type)) { - native_type.kind = GDScriptParser::DataType::UNRESOLVED; - } + native_type.kind = GDScriptParser::DataType::UNRESOLVED; } } } @@ -1765,9 +1762,8 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context, base_type = GDScriptParser::DataType(); break; } - StringName real_native = GDScriptParser::get_real_class_name(base_type.native_type); MethodInfo info; - if (ClassDB::get_method_info(real_native, p_context.current_function->identifier->name, &info)) { + if (ClassDB::get_method_info(base_type.native_type, p_context.current_function->identifier->name, &info)) { for (const PropertyInfo &E : info.arguments) { if (E.name == p_identifier) { r_type = _type_from_property(E); @@ -1836,13 +1832,12 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context, } // Check ClassDB. - StringName class_name = GDScriptParser::get_real_class_name(p_identifier); - if (ClassDB::class_exists(class_name) && ClassDB::is_class_exposed(class_name)) { + if (ClassDB::class_exists(p_identifier) && ClassDB::is_class_exposed(p_identifier)) { r_type.type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT; r_type.type.kind = GDScriptParser::DataType::NATIVE; r_type.type.native_type = p_identifier; r_type.type.is_constant = true; - r_type.type.is_meta_type = !Engine::get_singleton()->has_singleton(class_name); + r_type.type.is_meta_type = !Engine::get_singleton()->has_singleton(p_identifier); r_type.value = Variant(); } @@ -1951,7 +1946,7 @@ static bool _guess_identifier_type_from_base(GDScriptParser::CompletionContext & } } break; case GDScriptParser::DataType::NATIVE: { - StringName class_name = GDScriptParser::get_real_class_name(base_type.native_type); + StringName class_name = base_type.native_type; if (!ClassDB::class_exists(class_name)) { return false; } @@ -2113,11 +2108,10 @@ static bool _guess_method_return_type_from_base(GDScriptParser::CompletionContex } } break; case GDScriptParser::DataType::NATIVE: { - StringName native = GDScriptParser::get_real_class_name(base_type.native_type); - if (!ClassDB::class_exists(native)) { + if (!ClassDB::class_exists(base_type.native_type)) { return false; } - MethodBind *mb = ClassDB::get_method(native, p_method); + MethodBind *mb = ClassDB::get_method(base_type.native_type, p_method); if (mb) { r_type = _type_from_property(mb->get_return_info()); return true; @@ -2209,7 +2203,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c base_type = base_type.class_type->base_type; } break; case GDScriptParser::DataType::NATIVE: { - StringName class_name = GDScriptParser::get_real_class_name(base_type.native_type); + StringName class_name = base_type.native_type; if (!ClassDB::class_exists(class_name)) { base_type.kind = GDScriptParser::DataType::UNRESOLVED; break; @@ -2592,7 +2586,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c break; } - StringName class_name = GDScriptParser::get_real_class_name(native_type.native_type); + StringName class_name = native_type.native_type; if (!ClassDB::class_exists(class_name)) { break; } @@ -2821,7 +2815,7 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co } } break; case GDScriptParser::DataType::NATIVE: { - StringName class_name = GDScriptParser::get_real_class_name(base_type.native_type); + StringName class_name = base_type.native_type; if (!ClassDB::class_exists(class_name)) { base_type.kind = GDScriptParser::DataType::UNRESOLVED; break; @@ -2873,11 +2867,7 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co StringName parent = ClassDB::get_parent_class(class_name); if (parent != StringName()) { - if (String(parent).begins_with("_")) { - base_type.native_type = String(parent).substr(1); - } else { - base_type.native_type = parent; - } + base_type.native_type = parent; } else { base_type.kind = GDScriptParser::DataType::UNRESOLVED; } @@ -2931,18 +2921,11 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co } ::Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result) { - //before parsing, try the usual stuff + // Before parsing, try the usual stuff if (ClassDB::class_exists(p_symbol)) { r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS; r_result.class_name = p_symbol; return OK; - } else { - String under_prefix = "_" + p_symbol; - if (ClassDB::class_exists(under_prefix)) { - r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS; - r_result.class_name = p_symbol; - return OK; - } } for (int i = 0; i < Variant::VARIANT_MAX; i++) { diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index 9e5ef0f632..87d8c03494 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -111,11 +111,7 @@ public: } if (!ClassDB::is_parent_class(obj->get_class_name(), native_type)) { - // Try with underscore prefix - StringName underscore_native_type = "_" + native_type; - if (!ClassDB::is_parent_class(obj->get_class_name(), underscore_native_type)) { - return false; - } + return false; } return true; } break; diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 8c3bb1ea57..d21caf4389 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -94,43 +94,8 @@ Variant::Type GDScriptParser::get_builtin_type(const StringName &p_type) { return Variant::VARIANT_MAX; } -// TODO: Move this to a central location (maybe core?). -static HashMap<StringName, StringName> underscore_map; -static const char *underscore_classes[] = { - "ClassDB", - "Directory", - "Engine", - "File", - "Geometry", - "GodotSharp", - "JSON", - "Marshalls", - "Mutex", - "OS", - "ResourceLoader", - "ResourceSaver", - "Semaphore", - "Thread", - "VisualScriptEditor", - nullptr, -}; -StringName GDScriptParser::get_real_class_name(const StringName &p_source) { - if (underscore_map.is_empty()) { - const char **class_name = underscore_classes; - while (*class_name != nullptr) { - underscore_map[*class_name] = String("_") + *class_name; - class_name++; - } - } - if (underscore_map.has(p_source)) { - return underscore_map[p_source]; - } - return p_source; -} - void GDScriptParser::cleanup() { builtin_types.clear(); - underscore_map.clear(); } void GDScriptParser::get_annotation_list(List<MethodInfo> *r_annotations) const { @@ -3363,10 +3328,10 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node variable->export_info.hint_string = Variant::get_type_name(export_type.builtin_type); break; case GDScriptParser::DataType::NATIVE: - if (ClassDB::is_parent_class(get_real_class_name(export_type.native_type), "Resource")) { + if (ClassDB::is_parent_class(export_type.native_type, "Resource")) { variable->export_info.type = Variant::OBJECT; variable->export_info.hint = PROPERTY_HINT_RESOURCE_TYPE; - variable->export_info.hint_string = get_real_class_name(export_type.native_type); + variable->export_info.hint_string = export_type.native_type; } else { push_error(R"(Export type can only be built-in, a resource, or an enum.)", variable); return false; diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 6a227a55e5..0bce8d7ddd 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -1399,7 +1399,6 @@ public: ClassNode *get_tree() const { return head; } bool is_tool() const { return _is_tool; } static Variant::Type get_builtin_type(const StringName &p_type); - static StringName get_real_class_name(const StringName &p_source); CompletionContext get_completion_context() const { return completion_context; } CompletionCall get_completion_call() const { return completion_call; } diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp index 8164f459ca..6692a6efec 100644 --- a/modules/mono/editor/editor_internal_calls.cpp +++ b/modules/mono/editor/editor_internal_calls.cpp @@ -241,7 +241,7 @@ MonoBoolean godot_icall_Internal_IsAssembliesReloadingNeeded() { void godot_icall_Internal_ReloadAssemblies(MonoBoolean p_soft_reload) { #ifdef GD_MONO_HOT_RELOAD - _GodotSharp::get_singleton()->call_deferred(SNAME("_reload_assemblies"), (bool)p_soft_reload); + mono_bind::GodotSharp::get_singleton()->call_deferred(SNAME("_reload_assemblies"), (bool)p_soft_reload); #endif } diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 299344bb93..1b1349a3a3 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -73,7 +73,7 @@ #endif // TODO: -// This has turn into a gigantic mess. There's too much going on here. Too much #ifdef as well. +// This has turned into a gigantic mess. There's too much going on here. Too much #ifdef as well. // It's just painful to read... It needs to be re-structured. Please, clean this up, future me. GDMono *GDMono::singleton = nullptr; @@ -1335,23 +1335,25 @@ GDMono::~GDMono() { singleton = nullptr; } -_GodotSharp *_GodotSharp::singleton = nullptr; +namespace mono_bind { -void _GodotSharp::attach_thread() { +GodotSharp *GodotSharp::singleton = nullptr; + +void GodotSharp::attach_thread() { GDMonoUtils::attach_current_thread(); } -void _GodotSharp::detach_thread() { +void GodotSharp::detach_thread() { GDMonoUtils::detach_current_thread(); } -int32_t _GodotSharp::get_domain_id() { +int32_t GodotSharp::get_domain_id() { MonoDomain *domain = mono_domain_get(); ERR_FAIL_NULL_V(domain, -1); return mono_domain_get_id(domain); } -int32_t _GodotSharp::get_scripts_domain_id() { +int32_t GodotSharp::get_scripts_domain_id() { ERR_FAIL_NULL_V_MSG(GDMono::get_singleton(), -1, "The Mono runtime is not initialized"); MonoDomain *domain = GDMono::get_singleton()->get_scripts_domain(); @@ -1359,21 +1361,21 @@ int32_t _GodotSharp::get_scripts_domain_id() { return mono_domain_get_id(domain); } -bool _GodotSharp::is_scripts_domain_loaded() { +bool GodotSharp::is_scripts_domain_loaded() { return GDMono::get_singleton() != nullptr && GDMono::get_singleton()->is_runtime_initialized() && GDMono::get_singleton()->get_scripts_domain() != nullptr; } -bool _GodotSharp::_is_domain_finalizing_for_unload(int32_t p_domain_id) { +bool GodotSharp::_is_domain_finalizing_for_unload(int32_t p_domain_id) { return is_domain_finalizing_for_unload(p_domain_id); } -bool _GodotSharp::is_domain_finalizing_for_unload(int32_t p_domain_id) { +bool GodotSharp::is_domain_finalizing_for_unload(int32_t p_domain_id) { return is_domain_finalizing_for_unload(mono_domain_get_by_id(p_domain_id)); } -bool _GodotSharp::is_domain_finalizing_for_unload(MonoDomain *p_domain) { +bool GodotSharp::is_domain_finalizing_for_unload(MonoDomain *p_domain) { GDMono *gd_mono = GDMono::get_singleton(); ERR_FAIL_COND_V_MSG(!gd_mono || !gd_mono->is_runtime_initialized(), @@ -1388,15 +1390,15 @@ bool _GodotSharp::is_domain_finalizing_for_unload(MonoDomain *p_domain) { return mono_domain_is_unloading(p_domain); } -bool _GodotSharp::is_runtime_shutting_down() { +bool GodotSharp::is_runtime_shutting_down() { return mono_runtime_is_shutting_down(); } -bool _GodotSharp::is_runtime_initialized() { +bool GodotSharp::is_runtime_initialized() { return GDMono::get_singleton() != nullptr && GDMono::get_singleton()->is_runtime_initialized(); } -void _GodotSharp::_reload_assemblies(bool p_soft_reload) { +void GodotSharp::_reload_assemblies(bool p_soft_reload) { #ifdef GD_MONO_HOT_RELOAD CRASH_COND(CSharpLanguage::get_singleton() == nullptr); // This method may be called more than once with `call_deferred`, so we need to check @@ -1407,24 +1409,26 @@ void _GodotSharp::_reload_assemblies(bool p_soft_reload) { #endif } -void _GodotSharp::_bind_methods() { - ClassDB::bind_method(D_METHOD("attach_thread"), &_GodotSharp::attach_thread); - ClassDB::bind_method(D_METHOD("detach_thread"), &_GodotSharp::detach_thread); +void GodotSharp::_bind_methods() { + ClassDB::bind_method(D_METHOD("attach_thread"), &GodotSharp::attach_thread); + ClassDB::bind_method(D_METHOD("detach_thread"), &GodotSharp::detach_thread); - ClassDB::bind_method(D_METHOD("get_domain_id"), &_GodotSharp::get_domain_id); - ClassDB::bind_method(D_METHOD("get_scripts_domain_id"), &_GodotSharp::get_scripts_domain_id); - ClassDB::bind_method(D_METHOD("is_scripts_domain_loaded"), &_GodotSharp::is_scripts_domain_loaded); - ClassDB::bind_method(D_METHOD("is_domain_finalizing_for_unload", "domain_id"), &_GodotSharp::_is_domain_finalizing_for_unload); + ClassDB::bind_method(D_METHOD("get_domain_id"), &GodotSharp::get_domain_id); + ClassDB::bind_method(D_METHOD("get_scripts_domain_id"), &GodotSharp::get_scripts_domain_id); + ClassDB::bind_method(D_METHOD("is_scripts_domain_loaded"), &GodotSharp::is_scripts_domain_loaded); + ClassDB::bind_method(D_METHOD("is_domain_finalizing_for_unload", "domain_id"), &GodotSharp::_is_domain_finalizing_for_unload); - ClassDB::bind_method(D_METHOD("is_runtime_shutting_down"), &_GodotSharp::is_runtime_shutting_down); - ClassDB::bind_method(D_METHOD("is_runtime_initialized"), &_GodotSharp::is_runtime_initialized); - ClassDB::bind_method(D_METHOD("_reload_assemblies"), &_GodotSharp::_reload_assemblies); + ClassDB::bind_method(D_METHOD("is_runtime_shutting_down"), &GodotSharp::is_runtime_shutting_down); + ClassDB::bind_method(D_METHOD("is_runtime_initialized"), &GodotSharp::is_runtime_initialized); + ClassDB::bind_method(D_METHOD("_reload_assemblies"), &GodotSharp::_reload_assemblies); } -_GodotSharp::_GodotSharp() { +GodotSharp::GodotSharp() { singleton = this; } -_GodotSharp::~_GodotSharp() { +GodotSharp::~GodotSharp() { singleton = nullptr; } + +} // namespace mono_bind diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h index 5accc21f8e..4170e5053f 100644 --- a/modules/mono/mono_gd/gd_mono.h +++ b/modules/mono/mono_gd/gd_mono.h @@ -293,8 +293,10 @@ public: gdmono::ScopeExitDomainUnload __gdmono__scope__exit__domain__unload__(m_mono_domain); \ (void)__gdmono__scope__exit__domain__unload__; -class _GodotSharp : public Object { - GDCLASS(_GodotSharp, Object); +namespace mono_bind { + +class GodotSharp : public Object { + GDCLASS(GodotSharp, Object); friend class GDMono; @@ -303,11 +305,11 @@ class _GodotSharp : public Object { void _reload_assemblies(bool p_soft_reload); protected: - static _GodotSharp *singleton; + static GodotSharp *singleton; static void _bind_methods(); public: - static _GodotSharp *get_singleton() { return singleton; } + static GodotSharp *get_singleton() { return singleton; } void attach_thread(); void detach_thread(); @@ -323,8 +325,10 @@ public: bool is_runtime_shutting_down(); bool is_runtime_initialized(); - _GodotSharp(); - ~_GodotSharp(); + GodotSharp(); + ~GodotSharp(); }; +} // namespace mono_bind + #endif // GD_MONO_H diff --git a/modules/mono/register_types.cpp b/modules/mono/register_types.cpp index 2ba89eac55..98e83335e9 100644 --- a/modules/mono/register_types.cpp +++ b/modules/mono/register_types.cpp @@ -38,15 +38,15 @@ CSharpLanguage *script_language_cs = nullptr; Ref<ResourceFormatLoaderCSharpScript> resource_loader_cs; Ref<ResourceFormatSaverCSharpScript> resource_saver_cs; -_GodotSharp *_godotsharp = nullptr; +mono_bind::GodotSharp *_godotsharp = nullptr; void register_mono_types() { GDREGISTER_CLASS(CSharpScript); - _godotsharp = memnew(_GodotSharp); + _godotsharp = memnew(mono_bind::GodotSharp); - GDREGISTER_CLASS(_GodotSharp); - Engine::get_singleton()->add_singleton(Engine::Singleton("GodotSharp", _GodotSharp::get_singleton())); + GDREGISTER_CLASS(mono_bind::GodotSharp); + Engine::get_singleton()->add_singleton(Engine::Singleton("GodotSharp", mono_bind::GodotSharp::get_singleton())); script_language_cs = memnew(CSharpLanguage); script_language_cs->set_language_index(ScriptServer::get_language_count()); diff --git a/modules/visual_script/register_types.cpp b/modules/visual_script/register_types.cpp index f20ef046a3..fce98eb8a0 100644 --- a/modules/visual_script/register_types.cpp +++ b/modules/visual_script/register_types.cpp @@ -43,7 +43,7 @@ VisualScriptLanguage *visual_script_language = nullptr; #ifdef TOOLS_ENABLED -static _VisualScriptEditor *vs_editor_singleton = nullptr; +static vs_bind::VisualScriptEditor *vs_editor_singleton = nullptr; #endif void register_visual_script_types() { @@ -114,10 +114,10 @@ void register_visual_script_types() { #ifdef TOOLS_ENABLED ClassDB::set_current_api(ClassDB::API_EDITOR); - GDREGISTER_CLASS(_VisualScriptEditor); + GDREGISTER_CLASS(vs_bind::VisualScriptEditor); ClassDB::set_current_api(ClassDB::API_CORE); - vs_editor_singleton = memnew(_VisualScriptEditor); - Engine::get_singleton()->add_singleton(Engine::Singleton("VisualScriptEditor", _VisualScriptEditor::get_singleton())); + vs_editor_singleton = memnew(vs_bind::VisualScriptEditor); + Engine::get_singleton()->add_singleton(Engine::Singleton("VisualScriptEditor", vs_bind::VisualScriptEditor::get_singleton())); VisualScriptEditor::register_editor(); #endif diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index f3b6d74b7d..9d813e3d77 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -4521,44 +4521,49 @@ void VisualScriptEditor::register_editor() { EditorNode::add_plugin_init_callback(register_editor_callback); } -Ref<VisualScriptNode> _VisualScriptEditor::create_node_custom(const String &p_name) { +void VisualScriptEditor::validate() { +} + +namespace vs_bind { + +Ref<VisualScriptNode> VisualScriptEditor::create_node_custom(const String &p_name) { Ref<VisualScriptCustomNode> node; node.instantiate(); node->set_script(singleton->custom_nodes[p_name]); return node; } -_VisualScriptEditor *_VisualScriptEditor::singleton = nullptr; -Map<String, REF> _VisualScriptEditor::custom_nodes; +VisualScriptEditor *VisualScriptEditor::singleton = nullptr; +Map<String, REF> VisualScriptEditor::custom_nodes; -_VisualScriptEditor::_VisualScriptEditor() { +VisualScriptEditor::VisualScriptEditor() { singleton = this; } -_VisualScriptEditor::~_VisualScriptEditor() { +VisualScriptEditor::~VisualScriptEditor() { custom_nodes.clear(); } -void _VisualScriptEditor::add_custom_node(const String &p_name, const String &p_category, const Ref<Script> &p_script) { +void VisualScriptEditor::add_custom_node(const String &p_name, const String &p_category, const Ref<Script> &p_script) { String node_name = "custom/" + p_category + "/" + p_name; custom_nodes.insert(node_name, p_script); - VisualScriptLanguage::singleton->add_register_func(node_name, &_VisualScriptEditor::create_node_custom); + VisualScriptLanguage::singleton->add_register_func(node_name, &VisualScriptEditor::create_node_custom); emit_signal(SNAME("custom_nodes_updated")); } -void _VisualScriptEditor::remove_custom_node(const String &p_name, const String &p_category) { +void VisualScriptEditor::remove_custom_node(const String &p_name, const String &p_category) { String node_name = "custom/" + p_category + "/" + p_name; custom_nodes.erase(node_name); VisualScriptLanguage::singleton->remove_register_func(node_name); emit_signal(SNAME("custom_nodes_updated")); } -void _VisualScriptEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("add_custom_node", "name", "category", "script"), &_VisualScriptEditor::add_custom_node); - ClassDB::bind_method(D_METHOD("remove_custom_node", "name", "category"), &_VisualScriptEditor::remove_custom_node); +void VisualScriptEditor::_bind_methods() { + ClassDB::bind_method(D_METHOD("add_custom_node", "name", "category", "script"), &VisualScriptEditor::add_custom_node); + ClassDB::bind_method(D_METHOD("remove_custom_node", "name", "category"), &VisualScriptEditor::remove_custom_node); ADD_SIGNAL(MethodInfo("custom_nodes_updated")); } -void VisualScriptEditor::validate() { -} +} // namespace vs_bind + #endif diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h index 962ea380aa..6554c659e1 100644 --- a/modules/visual_script/visual_script_editor.h +++ b/modules/visual_script/visual_script_editor.h @@ -332,28 +332,33 @@ public: ~VisualScriptEditor(); }; +namespace vs_bind { + // Singleton -class _VisualScriptEditor : public Object { - GDCLASS(_VisualScriptEditor, Object); +class VisualScriptEditor : public Object { + GDCLASS(VisualScriptEditor, Object); friend class VisualScriptLanguage; protected: static void _bind_methods(); - static _VisualScriptEditor *singleton; + static VisualScriptEditor *singleton; static Map<String, REF> custom_nodes; static Ref<VisualScriptNode> create_node_custom(const String &p_name); public: - static _VisualScriptEditor *get_singleton() { return singleton; } + static VisualScriptEditor *get_singleton() { return singleton; } void add_custom_node(const String &p_name, const String &p_category, const Ref<Script> &p_script); void remove_custom_node(const String &p_name, const String &p_category); - _VisualScriptEditor(); - ~_VisualScriptEditor(); + VisualScriptEditor(); + ~VisualScriptEditor(); }; + +} // namespace vs_bind + #endif #endif // VISUALSCRIPT_EDITOR_H diff --git a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java index ad7048cbf3..3600706c7c 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java +++ b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java @@ -30,6 +30,7 @@ package org.godotengine.godot; +import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; import android.util.Log; @@ -86,6 +87,26 @@ public abstract class FullScreenGodotApp extends FragmentActivity implements God } @Override + public final void onGodotRestartRequested(Godot instance) { + if (instance == godotFragment) { + // HACK: + // + // Currently it's very hard to properly deinitialize Godot on Android to restart the game + // from scratch. Therefore, we need to kill the whole app process and relaunch it. + // + // Restarting only the activity, wouldn't be enough unless it did proper cleanup (including + // releasing and reloading native libs or resetting their state somehow and clearing statics). + // + // Using instrumentation is a way of making the whole app process restart, because Android + // will kill any process of the same package which was already running. + // + Bundle args = new Bundle(); + args.putParcelable("intent", getIntent()); + startInstrumentation(new ComponentName(this, GodotInstrumentation.class), null, args); + } + } + + @Override public void onNewIntent(Intent intent) { super.onNewIntent(intent); if (godotFragment != null) { diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java index 317175858b..2926031bcc 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java @@ -331,22 +331,8 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC } public void restart() { - // HACK: - // - // Currently it's very hard to properly deinitialize Godot on Android to restart the game - // from scratch. Therefore, we need to kill the whole app process and relaunch it. - // - // Restarting only the activity, wouldn't be enough unless it did proper cleanup (including - // releasing and reloading native libs or resetting their state somehow and clearing statics). - // - // Using instrumentation is a way of making the whole app process restart, because Android - // will kill any process of the same package which was already running. - // - final Activity activity = getActivity(); - if (activity != null) { - Bundle args = new Bundle(); - args.putParcelable("intent", mCurrentIntent); - activity.startInstrumentation(new ComponentName(activity, GodotInstrumentation.class), null, args); + if (godotHost != null) { + godotHost.onGodotRestartRequested(this); } } diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java b/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java index 58e982c569..7b22895994 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java @@ -58,4 +58,10 @@ public interface GodotHost { * Invoked on the UI thread as the last step of the Godot instance clean up phase. */ default void onGodotForceQuit(Godot instance) {} + + /** + * Invoked on the GL thread when the Godot instance wants to be restarted. It's up to the host + * to perform the appropriate action(s). + */ + default void onGodotRestartRequested(Godot instance) {} } diff --git a/platform/javascript/emscripten_helpers.py b/platform/javascript/emscripten_helpers.py index ab98838e20..4dad2d5204 100644 --- a/platform/javascript/emscripten_helpers.py +++ b/platform/javascript/emscripten_helpers.py @@ -24,7 +24,10 @@ def get_build_version(): v = "%d.%d" % (version.major, version.minor) if version.patch > 0: v += ".%d" % version.patch - v += ".%s.%s" % (version.status, name) + status = version.status + if os.getenv("GODOT_VERSION_STATUS") != None: + status = str(os.getenv("GODOT_VERSION_STATUS")) + v += ".%s.%s" % (status, name) return v diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index 13b37aa2b2..bf91ce8e65 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -261,6 +261,7 @@ void Camera2D::_notification(int p_what) { if (viewport && !(custom_viewport && !ObjectDB::get_instance(custom_viewport_id))) { viewport->set_canvas_transform(Transform2D()); clear_current(); + current = true; } } remove_from_group(group_name); diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 74eb3f2fc2..12aa1afc45 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -782,7 +782,7 @@ void TileMap::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List // Get the tile data. TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile)); Ref<ShaderMaterial> mat = tile_data->tile_get_material(); - int z_index = layers[q.layer].z_index + tile_data->get_z_index(); + int z_index = tile_data->get_z_index(); // Quandrant pos. Vector2 position = map_to_world(q.coords * get_effective_quadrant_size(q.layer)); diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index 508f8a70df..ab417fafdd 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -212,10 +212,6 @@ void Light3D::_validate_property(PropertyInfo &property) const { property.usage = PROPERTY_USAGE_NONE; } - if (get_light_type() == RS::LIGHT_SPOT && property.name == "shadow_normal_bias") { - property.usage = PROPERTY_USAGE_NONE; - } - if (get_light_type() == RS::LIGHT_DIRECTIONAL && property.name == "light_projector") { property.usage = PROPERTY_USAGE_NONE; } @@ -425,9 +421,7 @@ DirectionalLight3D::DirectionalLight3D() : set_param(PARAM_SHADOW_MAX_DISTANCE, 100); set_param(PARAM_SHADOW_FADE_START, 0.8); // Increase the default shadow bias to better suit most scenes. - // Leave normal bias untouched as it doesn't benefit DirectionalLight3D as much as OmniLight3D. set_param(PARAM_SHADOW_BIAS, 0.1); - set_param(PARAM_SHADOW_NORMAL_BIAS, 1.0); set_shadow_mode(SHADOW_PARALLEL_4_SPLITS); blend_splits = false; } @@ -468,8 +462,7 @@ OmniLight3D::OmniLight3D() : Light3D(RenderingServer::LIGHT_OMNI) { set_shadow_mode(SHADOW_CUBE); // Increase the default shadow biases to better suit most scenes. - set_param(PARAM_SHADOW_BIAS, 0.1); - set_param(PARAM_SHADOW_NORMAL_BIAS, 2.0); + set_param(PARAM_SHADOW_BIAS, 0.2); } TypedArray<String> SpotLight3D::get_configuration_warnings() const { diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 4bd88fde5f..aff367e398 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -358,9 +358,10 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) { } int button_idx = b->get_button_index(); - if (b->is_pressed() || (!b->is_pressed() && during_grabbed_click)) { - // Allow activating item by releasing the LMB or any that was down when the popup appeared. - // However, if button was not held when opening menu, do not allow release to activate item. + if (!b->is_pressed()) { + // Activate the item on release of either the left mouse button or + // any mouse button held down when the popup was opened. + // This allows for opening the popup and triggering an action in a single mouse click. if (button_idx == MOUSE_BUTTON_LEFT || (initial_button_mask & (1 << (button_idx - 1)))) { bool was_during_grabbed_click = during_grabbed_click; during_grabbed_click = false; diff --git a/scene/gui/shortcut.cpp b/scene/gui/shortcut.cpp index c0aac6d91a..d0cb08724e 100644 --- a/scene/gui/shortcut.cpp +++ b/scene/gui/shortcut.cpp @@ -32,7 +32,7 @@ #include "core/os/keyboard.h" void Shortcut::set_event(const Ref<InputEvent> &p_event) { - ERR_FAIL_COND(Object::cast_to<InputEventShortcut>(*p_event)); + ERR_FAIL_COND_MSG(Object::cast_to<InputEventShortcut>(*p_event), "Cannot set a shortcut event to an instance of InputEventShortcut."); event = p_event; emit_changed(); } diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 40ab439a51..6f8091c03f 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -812,7 +812,6 @@ void register_scene_types() { GDREGISTER_CLASS(Font); GDREGISTER_CLASS(Curve); - GDREGISTER_CLASS(TextFile); GDREGISTER_CLASS(TextLine); GDREGISTER_CLASS(TextParagraph); diff --git a/scene/resources/capsule_shape_2d.cpp b/scene/resources/capsule_shape_2d.cpp index 596fa70f15..0818e4fd99 100644 --- a/scene/resources/capsule_shape_2d.cpp +++ b/scene/resources/capsule_shape_2d.cpp @@ -59,7 +59,10 @@ void CapsuleShape2D::_update_shape() { } void CapsuleShape2D::set_radius(real_t p_radius) { - radius = MIN(p_radius, height * 0.5); + radius = p_radius; + if (radius > height * 0.5) { + height = radius * 2.0; + } _update_shape(); } @@ -68,7 +71,10 @@ real_t CapsuleShape2D::get_radius() const { } void CapsuleShape2D::set_height(real_t p_height) { - height = MAX(p_height, radius * 2); + height = p_height; + if (radius > height * 0.5) { + radius = height * 0.5; + } _update_shape(); } @@ -105,6 +111,8 @@ void CapsuleShape2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius"), "set_radius", "get_radius"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height"), "set_height", "get_height"); + ADD_LINKED_PROPERTY("radius", "height"); + ADD_LINKED_PROPERTY("height", "radius"); } CapsuleShape2D::CapsuleShape2D() : diff --git a/scene/resources/capsule_shape_3d.cpp b/scene/resources/capsule_shape_3d.cpp index e267941d6a..afec7b1877 100644 --- a/scene/resources/capsule_shape_3d.cpp +++ b/scene/resources/capsule_shape_3d.cpp @@ -81,7 +81,7 @@ void CapsuleShape3D::_update_shape() { void CapsuleShape3D::set_radius(float p_radius) { radius = p_radius; if (radius > height * 0.5) { - radius = height * 0.5; + height = radius * 2.0; } _update_shape(); notify_change_to_owners(); @@ -94,7 +94,7 @@ float CapsuleShape3D::get_radius() const { void CapsuleShape3D::set_height(float p_height) { height = p_height; if (radius > height * 0.5) { - height = radius * 2; + radius = height * 0.5; } _update_shape(); notify_change_to_owners(); @@ -112,6 +112,8 @@ void CapsuleShape3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.001,4096,0.001"), "set_radius", "get_radius"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0.001,4096,0.001"), "set_height", "get_height"); + ADD_LINKED_PROPERTY("radius", "height"); + ADD_LINKED_PROPERTY("height", "radius"); } CapsuleShape3D::CapsuleShape3D() : diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index ac7a500f73..1e1821024e 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -61,6 +61,7 @@ public: PARAM_MAX }; + // When extending, make sure not to overflow the size of the MaterialKey below. enum ParticleFlags { PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY, PARTICLE_FLAG_ROTATE_Y, @@ -68,6 +69,7 @@ public: PARTICLE_FLAG_MAX }; + // When extending, make sure not to overflow the size of the MaterialKey below. enum EmissionShape { EMISSION_SHAPE_POINT, EMISSION_SHAPE_SPHERE, @@ -78,6 +80,7 @@ public: EMISSION_SHAPE_MAX }; + // When extending, make sure not to overflow the size of the MaterialKey below. enum SubEmitterMode { SUB_EMITTER_DISABLED, SUB_EMITTER_CONSTANT, @@ -88,11 +91,13 @@ public: private: union MaterialKey { + // The bit size of the struct must be kept below or equal to 32 bits. + // Consider this when extending ParticleFlags, EmissionShape, or SubEmitterMode. struct { uint32_t texture_mask : 16; uint32_t texture_color : 1; uint32_t particle_flags : 4; - uint32_t emission_shape : 2; + uint32_t emission_shape : 3; uint32_t invalid_key : 1; uint32_t has_emission_color : 1; uint32_t sub_emitter : 2; diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp index 0c191fe2f7..3683622d3e 100644 --- a/servers/rendering/renderer_rd/effects_rd.cpp +++ b/servers/rendering/renderer_rd/effects_rd.cpp @@ -759,7 +759,7 @@ void EffectsRD::make_mipmap_raster(RID p_source_rd_texture, RID p_dest_framebuff RD::get_singleton()->draw_list_end(); } -void EffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, float p_z_near, float p_z_far, bool p_dp_flip) { +void EffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, const Vector2 &p_dst_size, float p_z_near, float p_z_far, bool p_dp_flip) { CopyToDPPushConstant push_constant; push_constant.screen_rect[0] = p_rect.position.x; push_constant.screen_rect[1] = p_rect.position.y; @@ -767,7 +767,9 @@ void EffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffe push_constant.screen_rect[3] = p_rect.size.height; push_constant.z_far = p_z_far; push_constant.z_near = p_z_near; - push_constant.z_flip = p_dp_flip; + push_constant.texel_size[0] = 1.0f / p_dst_size.x; + push_constant.texel_size[1] = 1.0f / p_dst_size.y; + push_constant.texel_size[0] *= p_dp_flip ? -1.0f : 1.0f; // Encode dp flip as x size sign RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ); RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, cube_to_dp.pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_framebuffer))); diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h index 0c9b2efb7f..c8d4cb7ad4 100644 --- a/servers/rendering/renderer_rd/effects_rd.h +++ b/servers/rendering/renderer_rd/effects_rd.h @@ -321,8 +321,7 @@ private: struct CopyToDPPushConstant { float z_far; float z_near; - uint32_t z_flip; - uint32_t pad; + float texel_size[2]; float screen_rect[4]; }; @@ -770,7 +769,7 @@ public: void cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size); void make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size); void make_mipmap_raster(RID p_source_rd_texture, RID p_dest_framebuffer, const Size2i &p_size); - void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2 &p_rect, float p_z_near, float p_z_far, bool p_dp_flip); + void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, const Vector2 &p_dst_size, float p_z_near, float p_z_far, bool p_dp_flip); void luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false); void luminance_reduction_raster(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, Vector<RID> p_fb, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index d81c216f37..8496ef631b 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -860,7 +860,7 @@ void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size, bool shadow_atlas->shadow_owners.clear(); shadow_atlas->size = p_size; - shadow_atlas->use_16_bits = p_size; + shadow_atlas->use_16_bits = p_16_bits; } void RendererSceneRenderRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) { @@ -935,7 +935,7 @@ bool RendererSceneRenderRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, //look for an empty space int sc = shadow_atlas->quadrants[qidx].shadows.size(); - ShadowAtlas::Quadrant::Shadow *sarr = shadow_atlas->quadrants[qidx].shadows.ptrw(); + const ShadowAtlas::Quadrant::Shadow *sarr = shadow_atlas->quadrants[qidx].shadows.ptr(); int found_free_idx = -1; //found a free one int found_used_idx = -1; //found existing one, must steal it @@ -980,6 +980,78 @@ bool RendererSceneRenderRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, return false; } +bool RendererSceneRenderRD::_shadow_atlas_find_omni_shadows(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow) { + for (int i = p_quadrant_count - 1; i >= 0; i--) { + int qidx = p_in_quadrants[i]; + + if (shadow_atlas->quadrants[qidx].subdivision == (uint32_t)p_current_subdiv) { + return false; + } + + //look for an empty space + int sc = shadow_atlas->quadrants[qidx].shadows.size(); + const ShadowAtlas::Quadrant::Shadow *sarr = shadow_atlas->quadrants[qidx].shadows.ptr(); + + int found_idx = -1; + uint64_t min_pass = 0; // sum of currently selected spots, try to get the least recently used pair + + for (int j = 0; j < sc - 1; j++) { + uint64_t pass = 0; + + if (sarr[j].owner.is_valid()) { + LightInstance *sli = light_instance_owner.getornull(sarr[j].owner); + ERR_CONTINUE(!sli); + + if (sli->last_scene_pass == scene_pass) { + continue; + } + + //was just allocated, don't kill it so soon, wait a bit.. + if (p_tick - sarr[j].alloc_tick < shadow_atlas_realloc_tolerance_msec) { + continue; + } + pass += sli->last_scene_pass; + } + + if (sarr[j + 1].owner.is_valid()) { + LightInstance *sli = light_instance_owner.getornull(sarr[j + 1].owner); + ERR_CONTINUE(!sli); + + if (sli->last_scene_pass == scene_pass) { + continue; + } + + //was just allocated, don't kill it so soon, wait a bit.. + if (p_tick - sarr[j + 1].alloc_tick < shadow_atlas_realloc_tolerance_msec) { + continue; + } + pass += sli->last_scene_pass; + } + + if (found_idx == -1 || pass < min_pass) { + found_idx = j; + min_pass = pass; + + // we found two empty spots, no need to check the rest + if (pass == 0) { + break; + } + } + } + + if (found_idx == -1) { + continue; //nothing found + } + + r_quadrant = qidx; + r_shadow = found_idx; + + return true; + } + + return false; +} + bool RendererSceneRenderRD::shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) { ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas); ERR_FAIL_COND_V(!shadow_atlas, false); @@ -1025,94 +1097,104 @@ bool RendererSceneRenderRD::shadow_atlas_update_light(RID p_atlas, RID p_light_i uint64_t tick = OS::get_singleton()->get_ticks_msec(); - //see if it already exists + uint32_t old_key = ShadowAtlas::SHADOW_INVALID; + uint32_t old_quadrant = ShadowAtlas::SHADOW_INVALID; + uint32_t old_shadow = ShadowAtlas::SHADOW_INVALID; + int old_subdivision = -1; + + bool should_realloc = false; + bool should_redraw = false; if (shadow_atlas->shadow_owners.has(p_light_intance)) { - //it does! - uint32_t key = shadow_atlas->shadow_owners[p_light_intance]; - uint32_t q = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3; - uint32_t s = key & ShadowAtlas::SHADOW_INDEX_MASK; + old_key = shadow_atlas->shadow_owners[p_light_intance]; + old_quadrant = (old_key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3; + old_shadow = old_key & ShadowAtlas::SHADOW_INDEX_MASK; - bool should_realloc = shadow_atlas->quadrants[q].subdivision != (uint32_t)best_subdiv && (shadow_atlas->quadrants[q].shadows[s].alloc_tick - tick > shadow_atlas_realloc_tolerance_msec); - bool should_redraw = shadow_atlas->quadrants[q].shadows[s].version != p_light_version; + should_realloc = shadow_atlas->quadrants[old_quadrant].subdivision != (uint32_t)best_subdiv && (shadow_atlas->quadrants[old_quadrant].shadows[old_shadow].alloc_tick - tick > shadow_atlas_realloc_tolerance_msec); + should_redraw = shadow_atlas->quadrants[old_quadrant].shadows[old_shadow].version != p_light_version; if (!should_realloc) { - shadow_atlas->quadrants[q].shadows.write[s].version = p_light_version; + shadow_atlas->quadrants[old_quadrant].shadows.write[old_shadow].version = p_light_version; //already existing, see if it should redraw or it's just OK return should_redraw; } - int new_quadrant, new_shadow; + old_subdivision = shadow_atlas->quadrants[old_quadrant].subdivision; + } - //find a better place - if (_shadow_atlas_find_shadow(shadow_atlas, valid_quadrants, valid_quadrant_count, shadow_atlas->quadrants[q].subdivision, tick, new_quadrant, new_shadow)) { - //found a better place! - ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows.write[new_shadow]; - if (sh->owner.is_valid()) { - //is taken, but is invalid, erasing it - shadow_atlas->shadow_owners.erase(sh->owner); - LightInstance *sli = light_instance_owner.getornull(sh->owner); - sli->shadow_atlases.erase(p_atlas); - } + bool is_omni = li->light_type == RS::LIGHT_OMNI; + bool found_shadow = false; + int new_quadrant = -1; + int new_shadow = -1; - //erase previous - shadow_atlas->quadrants[q].shadows.write[s].version = 0; - shadow_atlas->quadrants[q].shadows.write[s].owner = RID(); + if (is_omni) { + found_shadow = _shadow_atlas_find_omni_shadows(shadow_atlas, valid_quadrants, valid_quadrant_count, old_subdivision, tick, new_quadrant, new_shadow); + } else { + found_shadow = _shadow_atlas_find_shadow(shadow_atlas, valid_quadrants, valid_quadrant_count, old_subdivision, tick, new_quadrant, new_shadow); + } - sh->owner = p_light_intance; - sh->alloc_tick = tick; - sh->version = p_light_version; - li->shadow_atlases.insert(p_atlas); - - //make new key - key = new_quadrant << ShadowAtlas::QUADRANT_SHIFT; - key |= new_shadow; - //update it in map - shadow_atlas->shadow_owners[p_light_intance] = key; - //make it dirty, as it should redraw anyway - return true; + if (found_shadow) { + if (old_quadrant != ShadowAtlas::SHADOW_INVALID) { + shadow_atlas->quadrants[old_quadrant].shadows.write[old_shadow].version = 0; + shadow_atlas->quadrants[old_quadrant].shadows.write[old_shadow].owner = RID(); + + if (old_key & ShadowAtlas::OMNI_LIGHT_FLAG) { + shadow_atlas->quadrants[old_quadrant].shadows.write[old_shadow + 1].version = 0; + shadow_atlas->quadrants[old_quadrant].shadows.write[old_shadow + 1].owner = RID(); + } } - //no better place for this shadow found, keep current + uint32_t new_key = new_quadrant << ShadowAtlas::QUADRANT_SHIFT; + new_key |= new_shadow; - //already existing, see if it should redraw or it's just OK + ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows.write[new_shadow]; + _shadow_atlas_invalidate_shadow(sh, p_atlas, shadow_atlas, new_quadrant, new_shadow); - shadow_atlas->quadrants[q].shadows.write[s].version = p_light_version; + sh->owner = p_light_intance; + sh->alloc_tick = tick; + sh->version = p_light_version; - return should_redraw; - } + if (is_omni) { + new_key |= ShadowAtlas::OMNI_LIGHT_FLAG; - int new_quadrant, new_shadow; + int new_omni_shadow = new_shadow + 1; + ShadowAtlas::Quadrant::Shadow *extra_sh = &shadow_atlas->quadrants[new_quadrant].shadows.write[new_omni_shadow]; + _shadow_atlas_invalidate_shadow(extra_sh, p_atlas, shadow_atlas, new_quadrant, new_omni_shadow); - //find a better place - if (_shadow_atlas_find_shadow(shadow_atlas, valid_quadrants, valid_quadrant_count, -1, tick, new_quadrant, new_shadow)) { - //found a better place! - ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows.write[new_shadow]; - if (sh->owner.is_valid()) { - //is taken, but is invalid, erasing it - shadow_atlas->shadow_owners.erase(sh->owner); - LightInstance *sli = light_instance_owner.getornull(sh->owner); - sli->shadow_atlases.erase(p_atlas); + extra_sh->owner = p_light_intance; + extra_sh->alloc_tick = tick; + extra_sh->version = p_light_version; } - sh->owner = p_light_intance; - sh->alloc_tick = tick; - sh->version = p_light_version; li->shadow_atlases.insert(p_atlas); - //make new key - uint32_t key = new_quadrant << ShadowAtlas::QUADRANT_SHIFT; - key |= new_shadow; //update it in map - shadow_atlas->shadow_owners[p_light_intance] = key; + shadow_atlas->shadow_owners[p_light_intance] = new_key; //make it dirty, as it should redraw anyway - return true; } - //no place to allocate this light, apologies + return should_redraw; +} - return false; +void RendererSceneRenderRD::_shadow_atlas_invalidate_shadow(RendererSceneRenderRD::ShadowAtlas::Quadrant::Shadow *p_shadow, RID p_atlas, RendererSceneRenderRD::ShadowAtlas *p_shadow_atlas, uint32_t p_quadrant, uint32_t p_shadow_idx) { + if (p_shadow->owner.is_valid()) { + LightInstance *sli = light_instance_owner.getornull(p_shadow->owner); + uint32_t old_key = p_shadow_atlas->shadow_owners[p_shadow->owner]; + + if (old_key & ShadowAtlas::OMNI_LIGHT_FLAG) { + uint32_t s = old_key & ShadowAtlas::SHADOW_INDEX_MASK; + uint32_t omni_shadow_idx = p_shadow_idx + (s == (uint32_t)p_shadow_idx ? 1 : -1); + RendererSceneRenderRD::ShadowAtlas::Quadrant::Shadow *omni_shadow = &p_shadow_atlas->quadrants[p_quadrant].shadows.write[omni_shadow_idx]; + omni_shadow->version = 0; + omni_shadow->owner = RID(); + } + + p_shadow->version = 0; + p_shadow->owner = RID(); + sli->shadow_atlases.erase(p_atlas); + p_shadow_atlas->shadow_owners.erase(p_shadow->owner); + } } void RendererSceneRenderRD::_update_directional_shadow_atlas() { @@ -1137,6 +1219,7 @@ void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size, bool p } directional_shadow.size = p_size; + directional_shadow.use_16_bits = p_16_bits; if (directional_shadow.depth.is_valid()) { RD::get_singleton()->free(directional_shadow.depth); @@ -3120,18 +3203,19 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.shadow_enabled = true; - if (type == RS::LIGHT_SPOT) { - light_data.shadow_bias = (storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) / 100.0); + float shadow_texel_size = light_instance_get_shadow_texel_size(li->self, p_shadow_atlas); + light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 10.0; - } else { //omni + if (type == RS::LIGHT_SPOT) { light_data.shadow_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) / 100.0; - float shadow_texel_size = light_instance_get_shadow_texel_size(li->self, p_shadow_atlas); - light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 2.0; // applied in -1 .. 1 space + } else { //omni + light_data.shadow_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS); } light_data.transmittance_bias = storage->light_get_transmittance_bias(base); - Rect2 rect = light_instance_get_shadow_atlas_rect(li->self, p_shadow_atlas); + Vector2i omni_offset; + Rect2 rect = light_instance_get_shadow_atlas_rect(li->self, p_shadow_atlas, omni_offset); light_data.atlas_rect[0] = rect.position.x; light_data.atlas_rect[1] = rect.position.y; @@ -3142,7 +3226,6 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.shadow_volumetric_fog_fade = 1.0 / storage->light_get_shadow_volumetric_fog_fade(base); if (type == RS::LIGHT_OMNI) { - light_data.atlas_rect[3] *= 0.5; //one paraboloid on top of another Transform3D proj = (inverse_transform * light_transform).inverse(); RendererStorageRD::store_transform(proj, light_data.shadow_matrix); @@ -3154,6 +3237,8 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.soft_shadow_scale *= shadows_quality_radius_get(); // Only use quality radius for PCF } + light_data.direction[0] = omni_offset.x * float(rect.size.width); + light_data.direction[1] = omni_offset.y * float(rect.size.height); } else if (type == RS::LIGHT_SPOT) { Transform3D modelview = (inverse_transform * light_transform).inverse(); CameraMatrix bias; @@ -4139,6 +4224,7 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, bool using_dual_paraboloid = false; bool using_dual_paraboloid_flip = false; + Vector2i dual_paraboloid_offset; RID render_fb; RID render_texture; float zfar; @@ -4232,6 +4318,9 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, zfar = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE); if (storage->light_get_type(light_instance->light) == RS::LIGHT_OMNI) { + bool wrap = (shadow + 1) % shadow_atlas->quadrants[quadrant].subdivision == 0; + dual_paraboloid_offset = wrap ? Vector2i(1 - shadow_atlas->quadrants[quadrant].subdivision, 1) : Vector2i(1, 0); + if (storage->light_omni_get_shadow_mode(light_instance->light) == RS::LIGHT_OMNI_SHADOW_CUBE) { ShadowCubemap *cubemap = _get_shadow_cubemap(shadow_size / 2); @@ -4251,12 +4340,16 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, } } else { + atlas_rect.position.x += 1; + atlas_rect.position.y += 1; + atlas_rect.size.x -= 2; + atlas_rect.size.y -= 2; + + atlas_rect.position += p_pass * atlas_rect.size * dual_paraboloid_offset; + light_projection = light_instance->shadow_transform[0].camera; light_transform = light_instance->shadow_transform[0].transform; - atlas_rect.size.height /= 2; - atlas_rect.position.y += p_pass * atlas_rect.size.height; - using_dual_paraboloid = true; using_dual_paraboloid_flip = p_pass == 1; render_fb = shadow_atlas->fb; @@ -4285,10 +4378,9 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, atlas_rect_norm.position.y /= float(atlas_size); atlas_rect_norm.size.x /= float(atlas_size); atlas_rect_norm.size.y /= float(atlas_size); - atlas_rect_norm.size.height /= 2; - storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, light_projection.get_z_near(), light_projection.get_z_far(), false); - atlas_rect_norm.position.y += atlas_rect_norm.size.height; - storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, light_projection.get_z_near(), light_projection.get_z_far(), true); + storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, light_projection.get_z_near(), light_projection.get_z_far(), false); + atlas_rect_norm.position += Vector2(dual_paraboloid_offset) * atlas_rect_norm.size; + storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, light_projection.get_z_near(), light_projection.get_z_far(), true); //restore transform so it can be properly used light_instance_set_shadow_transform(p_light, CameraMatrix(), light_instance->transform, zfar, 0, 0, 0); @@ -4390,6 +4482,12 @@ bool RendererSceneRenderRD::free(RID p_rid) { uint32_t s = key & ShadowAtlas::SHADOW_INDEX_MASK; shadow_atlas->quadrants[q].shadows.write[s].owner = RID(); + + if (key & ShadowAtlas::OMNI_LIGHT_FLAG) { + // Omni lights use two atlas spots, make sure to clear the other as well + shadow_atlas->quadrants[q].shadows.write[s + 1].owner = RID(); + } + shadow_atlas->shadow_owners.erase(p_rid); } diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index a7cc27be4a..37533baecf 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -255,7 +255,8 @@ private: struct ShadowAtlas { enum { QUADRANT_SHIFT = 27, - SHADOW_INDEX_MASK = (1 << QUADRANT_SHIFT) - 1, + OMNI_LIGHT_FLAG = 1 << 26, + SHADOW_INDEX_MASK = OMNI_LIGHT_FLAG - 1, SHADOW_INVALID = 0xFFFFFFFF }; @@ -299,7 +300,9 @@ private: void _update_shadow_atlas(ShadowAtlas *shadow_atlas); + void _shadow_atlas_invalidate_shadow(RendererSceneRenderRD::ShadowAtlas::Quadrant::Shadow *p_shadow, RID p_atlas, RendererSceneRenderRD::ShadowAtlas *p_shadow_atlas, uint32_t p_quadrant, uint32_t p_shadow_idx); bool _shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow); + bool _shadow_atlas_find_omni_shadows(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow); RS::ShadowQuality shadows_quality = RS::SHADOW_QUALITY_MAX; //So it always updates when first set RS::ShadowQuality directional_shadow_quality = RS::SHADOW_QUALITY_MAX; @@ -379,10 +382,6 @@ private: uint32_t cull_mask = 0; uint32_t light_directional_index = 0; - uint32_t current_shadow_atlas_key = 0; - - Vector2 dp; - Rect2 directional_rect; Set<RID> shadow_atlases; //shadow atlases where this light is registered @@ -575,7 +574,7 @@ private: struct LightData { float position[3]; float inv_radius; - float direction[3]; + float direction[3]; // in omni, x and y are used for dual paraboloid offset float size; float color[3]; @@ -964,7 +963,7 @@ public: return li->transform; } - _FORCE_INLINE_ Rect2 light_instance_get_shadow_atlas_rect(RID p_light_instance, RID p_shadow_atlas) { + _FORCE_INLINE_ Rect2 light_instance_get_shadow_atlas_rect(RID p_light_instance, RID p_shadow_atlas, Vector2i &r_omni_offset) { ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); LightInstance *li = light_instance_owner.getornull(p_light_instance); uint32_t key = shadow_atlas->shadow_owners[li->self]; @@ -984,6 +983,16 @@ public: x += (shadow % shadow_atlas->quadrants[quadrant].subdivision) * shadow_size; y += (shadow / shadow_atlas->quadrants[quadrant].subdivision) * shadow_size; + if (key & ShadowAtlas::OMNI_LIGHT_FLAG) { + if (((shadow + 1) % shadow_atlas->quadrants[quadrant].subdivision) == 0) { + r_omni_offset.x = 1 - int(shadow_atlas->quadrants[quadrant].subdivision); + r_omni_offset.y = 1; + } else { + r_omni_offset.x = 1; + r_omni_offset.y = 0; + } + } + uint32_t width = shadow_size; uint32_t height = shadow_size; diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.cpp b/servers/rendering/renderer_rd/shader_compiler_rd.cpp index 8aa03b6426..bad37f5c25 100644 --- a/servers/rendering/renderer_rd/shader_compiler_rd.cpp +++ b/servers/rendering/renderer_rd/shader_compiler_rd.cpp @@ -213,7 +213,7 @@ static String _interpstr(SL::DataInterpolation p_interp) { return ""; } -static String _prestr(SL::DataPrecision p_pres) { +static String _prestr(SL::DataPrecision p_pres, bool p_force_highp = false) { switch (p_pres) { case SL::PRECISION_LOWP: return "lowp "; @@ -222,7 +222,7 @@ static String _prestr(SL::DataPrecision p_pres) { case SL::PRECISION_HIGHP: return "highp "; case SL::PRECISION_DEFAULT: - return ""; + return p_force_highp ? "highp " : ""; } return ""; } @@ -617,7 +617,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge //this is an integer to index the global table ucode += _typestr(ShaderLanguage::TYPE_UINT); } else { - ucode += _prestr(uniform.precision); + ucode += _prestr(uniform.precision, ShaderLanguage::is_float_type(uniform.type)); ucode += _typestr(uniform.type); } @@ -742,7 +742,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge String vcode; String interp_mode = _interpstr(varying.interpolation); - vcode += _prestr(varying.precision); + vcode += _prestr(varying.precision, ShaderLanguage::is_float_type(varying.type)); vcode += _typestr(varying.type); vcode += " " + _mkid(varying_name); if (varying.array_size > 0) { @@ -777,7 +777,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge const SL::ShaderNode::Constant &cnode = pnode->vconstants[i]; String gcode; gcode += "const "; - gcode += _prestr(cnode.precision); + gcode += _prestr(cnode.precision, ShaderLanguage::is_float_type(cnode.type)); if (cnode.type == SL::TYPE_STRUCT) { gcode += _mkid(cnode.type_str); } else { diff --git a/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl b/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl index dfbce29119..69b895ed29 100644 --- a/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl +++ b/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl @@ -7,8 +7,7 @@ layout(push_constant, binding = 1, std430) uniform Params { float z_far; float z_near; - bool z_flip; - uint pad; + vec2 texel_size; vec4 screen_rect; } params; @@ -35,22 +34,23 @@ layout(set = 0, binding = 0) uniform samplerCube source_cube; layout(push_constant, binding = 1, std430) uniform Params { float z_far; float z_near; - bool z_flip; - uint pad; + vec2 texel_size; vec4 screen_rect; } params; void main() { vec2 uv = uv_interp; + vec2 texel_size = abs(params.texel_size); - vec3 normal = vec3(uv * 2.0 - 1.0, 0.0); + uv = clamp(uv * (1.0 + 2.0 * texel_size) - texel_size, vec2(0.0), vec2(1.0)); - normal.z = 0.5 - 0.5 * ((normal.x * normal.x) + (normal.y * normal.y)); + vec3 normal = vec3(uv * 2.0 - 1.0, 0.0); + normal.z = 0.5 * (1.0 - dot(normal.xy, normal.xy)); // z = 1/2 - 1/2 * (x^2 + y^2) normal = normalize(normal); normal.y = -normal.y; //needs to be flipped to match projection matrix - if (!params.z_flip) { + if (params.texel_size.x >= 0.0) { // Sign is used to encode Z flip normal.z = -normal.z; } diff --git a/servers/rendering/renderer_rd/shaders/decal_data_inc.glsl b/servers/rendering/renderer_rd/shaders/decal_data_inc.glsl index ccaad13311..158096d3c7 100644 --- a/servers/rendering/renderer_rd/shaders/decal_data_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/decal_data_inc.glsl @@ -1,18 +1,18 @@ struct DecalData { - mat4 xform; //to decal transform - vec3 inv_extents; - float albedo_mix; - vec4 albedo_rect; - vec4 normal_rect; - vec4 orm_rect; - vec4 emission_rect; - vec4 modulate; - float emission_energy; + highp mat4 xform; //to decal transform + highp vec3 inv_extents; + mediump float albedo_mix; + highp vec4 albedo_rect; + highp vec4 normal_rect; + highp vec4 orm_rect; + highp vec4 emission_rect; + highp vec4 modulate; + mediump float emission_energy; uint mask; - float upper_fade; - float lower_fade; - mat3x4 normal_xform; - vec3 normal; - float normal_fade; + mediump float upper_fade; + mediump float lower_fade; + mediump mat3x4 normal_xform; + mediump vec3 normal; + mediump float normal_fade; }; diff --git a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl index 9155216d7e..fdc7729338 100644 --- a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl @@ -4,28 +4,28 @@ struct LightData { //this structure needs to be as packed as possible highp vec3 position; - float inv_radius; + highp float inv_radius; - vec3 direction; - float size; + mediump vec3 direction; + highp float size; - vec3 color; - float attenuation; + mediump vec3 color; + mediump float attenuation; - float cone_attenuation; - float cone_angle; - float specular_amount; + mediump float cone_attenuation; + mediump float cone_angle; + mediump float specular_amount; bool shadow_enabled; highp vec4 atlas_rect; // rect in the shadow atlas highp mat4 shadow_matrix; - float shadow_bias; - float shadow_normal_bias; - float transmittance_bias; - float soft_shadow_size; // for spot, it's the size in uv coordinates of the light, for omni it's the span angle - float soft_shadow_scale; // scales the shadow kernel for blurrier shadows + highp float shadow_bias; + highp float shadow_normal_bias; + highp float transmittance_bias; + highp float soft_shadow_size; // for spot, it's the size in uv coordinates of the light, for omni it's the span angle + highp float soft_shadow_scale; // scales the shadow kernel for blurrier shadows uint mask; - float shadow_volumetric_fog_fade; + mediump float shadow_volumetric_fog_fade; uint bake_mode; highp vec4 projector_rect; //projector rect in srgb decal atlas }; @@ -35,53 +35,53 @@ struct LightData { //this structure needs to be as packed as possible #define REFLECTION_AMBIENT_COLOR 2 struct ReflectionData { - vec3 box_extents; - float index; - vec3 box_offset; + highp vec3 box_extents; + mediump float index; + highp vec3 box_offset; uint mask; - vec3 ambient; // ambient color - float intensity; + mediump vec3 ambient; // ambient color + mediump float intensity; bool exterior; bool box_project; uint ambient_mode; uint pad; //0-8 is intensity,8-9 is ambient, mode - mat4 local_matrix; // up to here for spot and omni, rest is for directional + highp mat4 local_matrix; // up to here for spot and omni, rest is for directional // notes: for ambientblend, use distance to edge to blend between already existing global environment }; struct DirectionalLightData { - vec3 direction; - float energy; - vec3 color; - float size; - float specular; + mediump vec3 direction; + mediump float energy; + mediump vec3 color; + mediump float size; + mediump float specular; uint mask; - float softshadow_angle; - float soft_shadow_scale; + highp float softshadow_angle; + highp float soft_shadow_scale; bool blend_splits; bool shadow_enabled; - float fade_from; - float fade_to; + highp float fade_from; + highp float fade_to; uvec2 pad; uint bake_mode; - float shadow_volumetric_fog_fade; - vec4 shadow_bias; - vec4 shadow_normal_bias; - vec4 shadow_transmittance_bias; + mediump float shadow_volumetric_fog_fade; + highp vec4 shadow_bias; + highp vec4 shadow_normal_bias; + highp vec4 shadow_transmittance_bias; highp vec4 shadow_z_range; highp vec4 shadow_range_begin; - vec4 shadow_split_offsets; + highp vec4 shadow_split_offsets; highp mat4 shadow_matrix1; highp mat4 shadow_matrix2; highp mat4 shadow_matrix3; highp mat4 shadow_matrix4; - vec4 shadow_color1; - vec4 shadow_color2; - vec4 shadow_color3; - vec4 shadow_color4; - vec2 uv_scale1; - vec2 uv_scale2; - vec2 uv_scale3; - vec2 uv_scale4; + mediump vec4 shadow_color1; + mediump vec4 shadow_color2; + mediump vec4 shadow_color3; + mediump vec4 shadow_color4; + highp vec2 uv_scale1; + highp vec2 uv_scale2; + highp vec2 uv_scale3; + highp vec2 uv_scale4; }; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl index 4f140dd10d..adf9f20618 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl @@ -1601,7 +1601,7 @@ void main() { continue; // Statically baked light and object uses lightmap, skip } - float shadow = light_process_omni_shadow(light_index, vertex, view); + float shadow = light_process_omni_shadow(light_index, vertex, normal); shadow = blur_shadow(shadow); @@ -1677,7 +1677,7 @@ void main() { continue; // Statically baked light and object uses lightmap, skip } - float shadow = light_process_spot_shadow(light_index, vertex, view); + float shadow = light_process_spot_shadow(light_index, vertex, normal); shadow = blur_shadow(shadow); diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl index 4a41c66ef3..ef2fde7516 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl @@ -279,7 +279,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte } #ifdef USE_SHADOW_TO_OPACITY - alpha = min(alpha, clamp(1.0 - attenuation), 0.0, 1.0)); + alpha = min(alpha, clamp(1.0 - attenuation, 0.0, 1.0)); #endif #endif //defined(LIGHT_CODE_USED) @@ -320,7 +320,7 @@ float sample_directional_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, ve return avg * (1.0 / float(sc_directional_soft_shadow_samples)); } -float sample_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) { +float sample_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec3 coord) { vec2 pos = coord.xy; float depth = coord.z; @@ -346,6 +346,49 @@ float sample_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) { return avg * (1.0 / float(sc_soft_shadow_samples)); } +float sample_omni_pcf_shadow(texture2D shadow, float blur_scale, vec2 coord, vec4 uv_rect, vec2 flip_offset, float depth) { + //if only one sample is taken, take it from the center + if (sc_soft_shadow_samples == 1) { + vec2 pos = coord * 0.5 + 0.5; + pos = uv_rect.xy + pos * uv_rect.zw; + return textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos, depth, 1.0)); + } + + mat2 disk_rotation; + { + float r = quick_hash(gl_FragCoord.xy) * 2.0 * M_PI; + float sr = sin(r); + float cr = cos(r); + disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr)); + } + + float avg = 0.0; + vec2 offset_scale = blur_scale * 2.0 * scene_data.shadow_atlas_pixel_size / uv_rect.zw; + + for (uint i = 0; i < sc_soft_shadow_samples; i++) { + vec2 offset = offset_scale * (disk_rotation * scene_data.soft_shadow_kernel[i].xy); + vec2 sample_coord = coord + offset; + + float sample_coord_length_sqaured = dot(sample_coord, sample_coord); + bool do_flip = sample_coord_length_sqaured > 1.0; + + if (do_flip) { + float len = sqrt(sample_coord_length_sqaured); + sample_coord = sample_coord * (2.0 / len - 1.0); + } + + sample_coord = sample_coord * 0.5 + 0.5; + sample_coord = uv_rect.xy + sample_coord * uv_rect.zw; + + if (do_flip) { + sample_coord += flip_offset; + } + avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(sample_coord, depth, 1.0)); + } + + return avg * (1.0 / float(sc_soft_shadow_samples)); +} + float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex_scale) { //find blocker float blocker_count = 0.0; @@ -403,15 +446,21 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) { #ifndef USE_NO_SHADOWS if (omni_lights.data[idx].shadow_enabled) { // there is a shadowmap + vec2 texel_size = scene_data.shadow_atlas_pixel_size; + vec4 base_uv_rect = omni_lights.data[idx].atlas_rect; + base_uv_rect.xy += texel_size; + base_uv_rect.zw -= texel_size * 2.0; - vec3 light_rel_vec = omni_lights.data[idx].position - vertex; - float light_length = length(light_rel_vec); + // Omni lights use direction.xy to store to store the offset between the two paraboloid regions + vec2 flip_offset = omni_lights.data[idx].direction.xy; - vec4 v = vec4(vertex, 1.0); + vec3 local_vert = (omni_lights.data[idx].shadow_matrix * vec4(vertex, 1.0)).xyz; - vec4 splane = (omni_lights.data[idx].shadow_matrix * v); + float shadow_len = length(local_vert); //need to remember shadow len from here + vec3 shadow_dir = normalize(local_vert); - float shadow_len = length(splane.xyz); //need to remember shadow len from here + vec3 local_normal = normalize(mat3(omni_lights.data[idx].shadow_matrix) * normal); + vec3 normal_bias = local_normal * omni_lights.data[idx].shadow_normal_bias * (1.0 - abs(dot(local_normal, shadow_dir))); float shadow; @@ -431,10 +480,10 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) { disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr)); } - vec3 normal = normalize(splane.xyz); - vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0); - vec3 tangent = normalize(cross(v0, normal)); - vec3 bitangent = normalize(cross(tangent, normal)); + vec3 basis_normal = shadow_dir; + vec3 v0 = abs(basis_normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0); + vec3 tangent = normalize(cross(v0, basis_normal)); + vec3 bitangent = normalize(cross(tangent, basis_normal)); float z_norm = shadow_len * omni_lights.data[idx].inv_radius; tangent *= omni_lights.data[idx].soft_shadow_size * omni_lights.data[idx].soft_shadow_scale; @@ -443,18 +492,17 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) { for (uint i = 0; i < sc_penumbra_shadow_samples; i++) { vec2 disk = disk_rotation * scene_data.penumbra_shadow_kernel[i].xy; - vec3 pos = splane.xyz + tangent * disk.x + bitangent * disk.y; + vec3 pos = local_vert + tangent * disk.x + bitangent * disk.y; pos = normalize(pos); - vec4 uv_rect = omni_lights.data[idx].atlas_rect; + + vec4 uv_rect = base_uv_rect; if (pos.z >= 0.0) { - pos.z += 1.0; - uv_rect.y += uv_rect.w; - } else { - pos.z = 1.0 - pos.z; + uv_rect.xy += flip_offset; } + pos.z = 1.0 + abs(pos.z); pos.xy /= pos.z; pos.xy = pos.xy * 0.5 + 0.5; @@ -479,18 +527,18 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) { shadow = 0.0; for (uint i = 0; i < sc_penumbra_shadow_samples; i++) { vec2 disk = disk_rotation * scene_data.penumbra_shadow_kernel[i].xy; - vec3 pos = splane.xyz + tangent * disk.x + bitangent * disk.y; + vec3 pos = local_vert + tangent * disk.x + bitangent * disk.y; pos = normalize(pos); - vec4 uv_rect = omni_lights.data[idx].atlas_rect; + pos = normalize(pos + normal_bias); + + vec4 uv_rect = base_uv_rect; if (pos.z >= 0.0) { - pos.z += 1.0; - uv_rect.y += uv_rect.w; - } else { - pos.z = 1.0 - pos.z; + uv_rect.xy += flip_offset; } + pos.z = 1.0 + abs(pos.z); pos.xy /= pos.z; pos.xy = pos.xy * 0.5 + 0.5; @@ -505,26 +553,19 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) { shadow = 1.0; } } else { - splane.xyz = normalize(splane.xyz); - vec4 clamp_rect = omni_lights.data[idx].atlas_rect; - - if (splane.z >= 0.0) { - splane.z += 1.0; + vec4 uv_rect = base_uv_rect; - clamp_rect.y += clamp_rect.w; - - } else { - splane.z = 1.0 - splane.z; + vec3 shadow_sample = normalize(shadow_dir + normal_bias); + if (shadow_sample.z >= 0.0) { + uv_rect.xy += flip_offset; + flip_offset *= -1.0; } - splane.xy /= splane.z; - - splane.xy = splane.xy * 0.5 + 0.5; - splane.z = shadow_len * omni_lights.data[idx].inv_radius; - splane.z -= omni_lights.data[idx].shadow_bias; - splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw; - splane.w = 1.0; //needed? i think it should be 1 already - shadow = sample_pcf_shadow(shadow_atlas, omni_lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, splane); + shadow_sample.z = 1.0 + abs(shadow_sample.z); + vec2 pos = shadow_sample.xy / shadow_sample.z; + float depth = shadow_len - omni_lights.data[idx].shadow_bias; + depth *= omni_lights.data[idx].inv_radius; + shadow = sample_omni_pcf_shadow(shadow_atlas, omni_lights.data[idx].soft_shadow_scale / shadow_sample.z, pos, uv_rect, flip_offset, depth); } return shadow; @@ -608,13 +649,11 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v vec4 atlas_rect = omni_lights.data[idx].projector_rect; if (local_v.z >= 0.0) { - local_v.z += 1.0; atlas_rect.y += atlas_rect.w; - - } else { - local_v.z = 1.0 - local_v.z; } + local_v.z = 1.0 + abs(local_v.z); + local_v.xy /= local_v.z; local_v.xy = local_v.xy * 0.5 + 0.5; vec2 proj_uv = local_v.xy * atlas_rect.zw; @@ -694,15 +733,18 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) { vec3 light_rel_vec = spot_lights.data[idx].position - vertex; float light_length = length(light_rel_vec); vec3 spot_dir = spot_lights.data[idx].direction; - //there is a shadowmap - vec4 v = vec4(vertex, 1.0); - float shadow; + vec3 shadow_dir = light_rel_vec / light_length; + vec3 normal_bias = normal * light_length * spot_lights.data[idx].shadow_normal_bias * (1.0 - abs(dot(normal, shadow_dir))); + + //there is a shadowmap + vec4 v = vec4(vertex + normal_bias, 1.0); vec4 splane = (spot_lights.data[idx].shadow_matrix * v); + splane.z -= spot_lights.data[idx].shadow_bias / (light_length * spot_lights.data[idx].inv_radius); splane /= splane.w; - splane.z -= spot_lights.data[idx].shadow_bias; + float shadow; if (sc_use_light_soft_shadows && spot_lights.data[idx].soft_shadow_size > 0.0) { //soft shadow @@ -753,11 +795,9 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) { //no blockers found, so no shadow shadow = 1.0; } - } else { //hard shadow - vec4 shadow_uv = vec4(splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy, splane.z, 1.0); - + vec3 shadow_uv = vec3(splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy, splane.z); shadow = sample_pcf_shadow(shadow_atlas, spot_lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, shadow_uv); } diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl index 663100a0b3..a2a54a0511 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl @@ -92,7 +92,7 @@ layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms #ifdef MODE_DUAL_PARABOLOID -layout(location = 8) out float dp_clip; +layout(location = 8) out highp float dp_clip; #endif @@ -370,11 +370,6 @@ void main() { #VERSION_DEFINES -//use medium precision for floats on mobile. - -precision mediump float; -precision highp int; - /* Specialization Constants */ #if !defined(MODE_RENDER_DEPTH) @@ -498,7 +493,7 @@ layout(location = 0) out vec4 diffuse_buffer; //diffuse (rgb) and roughness layout(location = 1) out vec4 specular_buffer; //specular and SSS (subsurface scatter) #else -layout(location = 0) out vec4 frag_color; +layout(location = 0) out mediump vec4 frag_color; #endif // MODE_MULTIPLE_RENDER_TARGETS #endif // RENDER DEPTH @@ -1392,7 +1387,7 @@ void main() { break; } - float shadow = light_process_omni_shadow(light_index, vertex, view); + float shadow = light_process_omni_shadow(light_index, vertex, normal); shadow = blur_shadow(shadow); @@ -1440,7 +1435,7 @@ void main() { break; } - float shadow = light_process_spot_shadow(light_index, vertex, view); + float shadow = light_process_spot_shadow(light_index, vertex, normal); shadow = blur_shadow(shadow); diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl index f1e554d01c..dd8879acb4 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl @@ -93,7 +93,7 @@ directional_lights; #define LIGHTMAP_FLAG_USE_SPECULAR_DIRECTION 2 struct Lightmap { - mat3 normal_xform; + mediump mat3 normal_xform; }; layout(set = 0, binding = 9, std140) restrict readonly buffer Lightmaps { @@ -102,7 +102,7 @@ layout(set = 0, binding = 9, std140) restrict readonly buffer Lightmaps { lightmaps; struct LightmapCapture { - vec4 sh[9]; + mediump vec4 sh[9]; }; layout(set = 0, binding = 10, std140) restrict readonly buffer LightmapCaptures { @@ -110,8 +110,8 @@ layout(set = 0, binding = 10, std140) restrict readonly buffer LightmapCaptures } lightmap_captures; -layout(set = 0, binding = 11) uniform texture2D decal_atlas; -layout(set = 0, binding = 12) uniform texture2D decal_atlas_srgb; +layout(set = 0, binding = 11) uniform mediump texture2D decal_atlas; +layout(set = 0, binding = 12) uniform mediump texture2D decal_atlas_srgb; layout(set = 0, binding = 13, std430) restrict readonly buffer Decals { DecalData data[]; @@ -119,7 +119,7 @@ layout(set = 0, binding = 13, std430) restrict readonly buffer Decals { decals; layout(set = 0, binding = 14, std430) restrict readonly buffer GlobalVariableData { - vec4 data[]; + highp vec4 data[]; } global_variables; @@ -135,56 +135,56 @@ layout(set = 1, binding = 0, std140) uniform SceneData { highp mat4 projection_matrix_view[MAX_VIEWS]; highp mat4 inv_projection_matrix_view[MAX_VIEWS]; - vec2 viewport_size; - vec2 screen_pixel_size; + highp vec2 viewport_size; + highp vec2 screen_pixel_size; // Use vec4s because std140 doesn't play nice with vec2s, z and w are wasted. - vec4 directional_penumbra_shadow_kernel[32]; - vec4 directional_soft_shadow_kernel[32]; - vec4 penumbra_shadow_kernel[32]; - vec4 soft_shadow_kernel[32]; + highp vec4 directional_penumbra_shadow_kernel[32]; + highp vec4 directional_soft_shadow_kernel[32]; + highp vec4 penumbra_shadow_kernel[32]; + highp vec4 soft_shadow_kernel[32]; - vec4 ambient_light_color_energy; + mediump vec4 ambient_light_color_energy; - float ambient_color_sky_mix; + mediump float ambient_color_sky_mix; bool use_ambient_light; bool use_ambient_cubemap; bool use_reflection_cubemap; - mat3 radiance_inverse_xform; + mediump mat3 radiance_inverse_xform; - vec2 shadow_atlas_pixel_size; - vec2 directional_shadow_pixel_size; + highp vec2 shadow_atlas_pixel_size; + highp vec2 directional_shadow_pixel_size; uint directional_light_count; - float dual_paraboloid_side; - float z_far; - float z_near; + mediump float dual_paraboloid_side; + highp float z_far; + highp float z_near; bool ssao_enabled; - float ssao_light_affect; - float ssao_ao_affect; + mediump float ssao_light_affect; + mediump float ssao_ao_affect; bool roughness_limiter_enabled; - float roughness_limiter_amount; - float roughness_limiter_limit; + mediump float roughness_limiter_amount; + mediump float roughness_limiter_limit; uvec2 roughness_limiter_pad; - vec4 ao_color; + mediump vec4 ao_color; bool fog_enabled; - float fog_density; - float fog_height; - float fog_height_density; + highp float fog_density; + highp float fog_height; + highp float fog_height_density; - vec3 fog_light_color; - float fog_sun_scatter; + mediump vec3 fog_light_color; + mediump float fog_sun_scatter; - float fog_aerial_perspective; + mediump float fog_aerial_perspective; bool material_uv2_mode; - float time; - float reflection_multiplier; // one normally, zero when rendering reflections + highp float time; + mediump float reflection_multiplier; // one normally, zero when rendering reflections bool pancake_shadows; uint pad1; @@ -195,30 +195,30 @@ scene_data; #ifdef USE_RADIANCE_CUBEMAP_ARRAY -layout(set = 1, binding = 2) uniform textureCubeArray radiance_cubemap; +layout(set = 1, binding = 2) uniform mediump textureCubeArray radiance_cubemap; #else -layout(set = 1, binding = 2) uniform textureCube radiance_cubemap; +layout(set = 1, binding = 2) uniform mediump textureCube radiance_cubemap; #endif -layout(set = 1, binding = 3) uniform textureCubeArray reflection_atlas; +layout(set = 1, binding = 3) uniform mediump textureCubeArray reflection_atlas; -layout(set = 1, binding = 4) uniform texture2D shadow_atlas; +layout(set = 1, binding = 4) uniform highp texture2D shadow_atlas; -layout(set = 1, binding = 5) uniform texture2D directional_shadow_atlas; +layout(set = 1, binding = 5) uniform highp texture2D directional_shadow_atlas; // this needs to change to providing just the lightmap we're using.. layout(set = 1, binding = 6) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES]; -layout(set = 1, binding = 9) uniform texture2D depth_buffer; -layout(set = 1, binding = 10) uniform texture2D color_buffer; +layout(set = 1, binding = 9) uniform highp texture2D depth_buffer; +layout(set = 1, binding = 10) uniform mediump texture2D color_buffer; /* Set 2 Skeleton & Instancing (can change per item) */ layout(set = 2, binding = 0, std430) restrict readonly buffer Transforms { - vec4 data[]; + highp vec4 data[]; } transforms; diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index 4a4976718c..cd8014632d 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -2180,8 +2180,6 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons p_scenario->indexers[Scenario::INDEXER_GEOMETRY].convex_query(planes.ptr(), planes.size(), points.ptr(), points.size(), cull_convex); - Plane near_plane(light_transform.origin, light_transform.basis.get_axis(2) * z); - RendererSceneRender::RenderShadowData &shadow_data = render_shadow_data[max_shadows_used++]; for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) { @@ -2215,7 +2213,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); CameraMatrix cm; - cm.set_perspective(90, 1, 0.01, radius); + cm.set_perspective(90, 1, radius * 0.005f, radius); for (int i = 0; i < 6; i++) { RENDER_TIMESTAMP("Culling Shadow Cube side" + itos(i)); @@ -2301,7 +2299,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons real_t angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SPOT_ANGLE); CameraMatrix cm; - cm.set_perspective(angle * 2.0, 1.0, 0.01, radius); + cm.set_perspective(angle * 2.0, 1.0, 0.005f * radius, radius); Vector<Plane> planes = cm.get_projection_planes(light_transform); @@ -2794,12 +2792,9 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c //rasterizer->set_camera(p_camera_data->main_transform, p_camera_data.main_projection, p_camera_data.is_ortogonal); - Vector<Plane> planes = p_camera_data->main_projection.get_projection_planes(p_camera_data->main_transform); - - Plane near_plane(p_camera_data->main_transform.origin, -p_camera_data->main_transform.basis.get_axis(2).normalized()); - /* STEP 2 - CULL */ + Vector<Plane> planes = p_camera_data->main_projection.get_projection_planes(p_camera_data->main_transform); cull.frustum = Frustum(planes); Vector<RID> directional_lights; diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 20fcb1396d..4218214fda 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -2877,6 +2877,27 @@ bool ShaderLanguage::is_scalar_type(DataType p_type) { return p_type == TYPE_BOOL || p_type == TYPE_INT || p_type == TYPE_UINT || p_type == TYPE_FLOAT; } +bool ShaderLanguage::is_float_type(DataType p_type) { + switch (p_type) { + case TYPE_FLOAT: + case TYPE_VEC2: + case TYPE_VEC3: + case TYPE_VEC4: + case TYPE_MAT2: + case TYPE_MAT3: + case TYPE_MAT4: + case TYPE_SAMPLER2D: + case TYPE_SAMPLER2DARRAY: + case TYPE_SAMPLER3D: + case TYPE_SAMPLERCUBE: + case TYPE_SAMPLERCUBEARRAY: { + return true; + } + default: { + return false; + } + } +} bool ShaderLanguage::is_sampler_type(DataType p_type) { return p_type == TYPE_SAMPLER2D || p_type == TYPE_ISAMPLER2D || diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index 9e0a63f0f7..18525e054e 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -774,6 +774,7 @@ public: static DataType get_scalar_type(DataType p_type); static int get_cardinality(DataType p_type); static bool is_scalar_type(DataType p_type); + static bool is_float_type(DataType p_type); static bool is_sampler_type(DataType p_type); static Variant constant_value_to_variant(const Vector<ShaderLanguage::ConstantNode::Value> &p_value, DataType p_type, ShaderLanguage::ShaderNode::Uniform::Hint p_hint = ShaderLanguage::ShaderNode::Uniform::HINT_NONE); static PropertyInfo uniform_to_property_info(const ShaderNode::Uniform &p_uniform); diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index 4488069698..0bfcccef28 100644 --- a/servers/rendering/shader_types.cpp +++ b/servers/rendering/shader_types.cpp @@ -342,7 +342,6 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["VELOCITY"] = ShaderLanguage::TYPE_VEC3; shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["MASS"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["ACTIVE"] = ShaderLanguage::TYPE_BOOL; - shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["RESTART"] = constt(ShaderLanguage::TYPE_BOOL); shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["CUSTOM"] = ShaderLanguage::TYPE_VEC4; shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["TRANSFORM"] = ShaderLanguage::TYPE_MAT4; shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["LIFETIME"] = constt(ShaderLanguage::TYPE_FLOAT); |